So class A has a collection of class B and class B has some properties.
class A(object):
bs = []
class B(object):
propertyA
propertyB
I need to be able to traverse the collection from the root of the aggregate and find all differencies between to aggregates.
So for example, one instance of A can differ from another by having additional B instance and by not having some B instance. And I need to do this recusively for every B that is in common beetween them.
A and B are value objects, so their identity completely depends on their attributes.
Right now I have three classed to incapsulate differencies
ElementExistsDifference
ElementNotExistsDifference
ElementPropertyDifference.
Which are defined as:
from abc import ABCMeta, abstractmethod
__author__ = 'michael'
class Differ():
def __init__(self, one_item, another_item, difference):
self.another_item = another_item
self.one_item = one_item
self.difference = difference
def __repr__(self, *args, **kwargs):
one_str = str(self.one_item)
two_str = str(self.two_item)
diff_str = str(self.difference)
return "{} differ from {} by {}".format(one_str, two_str, diff_str)
class AbstractDifference(metaclass=ABCMeta):
#abstractmethod
def compensate(self, db_api):
pass
class NoDifference(AbstractDifference):
def compensate(self, db_api):
pass
def __repr__(self):
return "Nothing"
class ItemDifference(AbstractDifference):
#abstractmethod
def compensate(self, db_api):
pass
def __init__(self, item):
self.item = item
def __repr__(self):
return str(self.item)
class ExistsDifference(SchemaItemDifference):
def compensate(self, api):
pass
def __repr__(self):
item = super()
return "Existence of {}".format(item)
class NotExistsDifference(ItemDifference):
def compensate(self, api):
pass
def __repr__(self):
item = super()
return "Abscence of {}".format(item)
class ItemPropertyDifference(AbstractDifference):
def compensate(self, api):
pass
def __init__(self, property):
self.property = property
def __repr__(self):
return str(self.property)
Any suggestions on how to do this?
It looks like you have thought about this problem a bit, considering the classes you have created. I am going to describe my own thought process regarding this problem and then define similar classes. Hopefully this will help you complete your solution.
You have value objects which have attributes. Those attributes can be plain values or they can be value objects.
You need to compare two trees to determine the differences between the two trees. You have defined many classes which you hope to annotate the differences in structure. I think that this is a good approach, however I think that you only need two classes to represent the difference.
class Match(object):
def __init__(self, one, two):
self.one = one
self.two = two
def add_comparison(self, attribute, comparison):
""" This adds the Match or Difference class for the attribute """
setattr(self, attribute, comparison)
class Difference(object):
def __init__(self, one, two):
self.one = one
self.two = two
These two classes represent two objects or values which either match or differ.
If two value objects are present for the same attribute in their parent then they are considered to match. If the value objects have completely different attributes then they still match, but the attributes differ. The match holds references to the actual values so you can print them as required.
If two values are present for the same attribute in their parent and their values are equal then they are considered to match. Since they are not value objects there is no further comparison done.
If an attribute is missing, or an attribute differs substantially (i.e. one is a value object and another is a plain value) then they are considered to differ.
With these classes and rules we can then define the actual matcher. I have strived to use clear method names, but I have not implemented all the methods that this code uses. You will have to complete them. Hopefully that will not be too hard!
def generate_match_tree(one, two):
# The is_value_object function should be able to handle None
if not is_value_object(one) and not is_value_object(two):
# If you need to handle lists then you would do that here
if one == two:
return Match(one, two)
else:
return Difference(one, two)
if not is_value_object(one) or not is_value_object(two):
return Difference(one, two)
# Here we know one and two are both value objects, so they match.
# We must consider the attributes of them now...
result = Match(one, two)
for attribute in get_all_attributes(one) + get_all_attributes(two):
a_one = getattr(one, attribute)
a_two = getattr(two, attribute)
result.add_comparison(attribute, generate_match_tree(a_one, a_two))
return result
Let me know if you need any more help.
Related
Specifically, I would want MyClass.my_method to be used for lookup of a value in the class dictionary, but MyClass.my_method() to be a method that accepts arguments and performs a computation to update an attribute in MyClass and then returns MyClass with all its attributes (including the updated one).
I am thinking that this might be doable with Python's descriptors (maybe overriding __get__ or __call__), but I can't figure out how this would look. I understand that the behavior might be confusing, but I am interested if it is possible (and if there are any other major caveats).
I have seen that you can do something similar for classes and functions by overriding __repr__, but I can't find a similar way for a method within a class. My returned value will also not always be a string, which seems to prohibit the __repr__-based approaches mentioned in these two questions:
Possible to change a function's repr in python?
How to create a custom string representation for a class object?
Thank you Joel for the minimal implementation. I found that the remaining problem is the lack of initialization of the parent, since I did not find a generic way of initializing it, I need to check for attributes in the case of list/dict, and add the initialization values to the parent accordingly.
This addition to the code should make it work for lists/dicts:
def classFactory(parent, init_val, target):
class modifierClass(parent):
def __init__(self, init_val):
super().__init__()
dict_attr = getattr(parent, "update", None)
list_attr = getattr(parent, "extend", None)
if callable(dict_attr): # parent is dict
self.update(init_val)
elif callable(list_attr): # parent is list
self.extend(init_val)
self.target = target
def __call__(self, *args):
self.target.__init__(*args)
return modifierClass(init_val)
class myClass:
def __init__(self, init_val=''):
self.method = classFactory(init_val.__class__, init_val, self)
Unfortunately, we need to add case by case, but this works as intended.
A slightly less verbose way to write the above is the following:
def classFactory(parent, init_val, target):
class modifierClass(parent):
def __init__(self, init_val):
if isinstance(init_val, list):
self.extend(init_val)
elif isinstance(init_val, dict):
self.update(init_val)
self.target = target
def __call__(self, *args):
self.target.__init__(*args)
return modifierClass(init_val)
class myClass:
def __init__(self, init_val=''):
self.method = classFactory(init_val.__class__, init_val, self)
As jasonharper commented,
MyClass.my_method() works by looking up MyClass.my_method, and then attempting to call that object. So the result of MyClass.my_method cannot be a plain string, int, or other common data type [...]
The trouble comes specifically from reusing the same name for this two properties, which is very confusing just as you said. So, don't do it.
But for the sole interest of it you could try to proxy the value of the property with an object that would return the original MyClass instance when called, use an actual setter to perform any computation you wanted, and also forward arbitrary attributes to the proxied value.
class MyClass:
_my_method = whatever
#property
def my_method(self):
my_class = self
class Proxy:
def __init__(self, value):
self.__proxied = value
def __call__(self, value):
my_class.my_method = value
return my_class
def __getattr__(self, name):
return getattr(self.__proxied, name)
def __str__(self):
return str(self.__proxied)
def __repr__(self):
return repr(self.__proxied)
return Proxy(self._my_method)
#my_method.setter
def my_method(self, value):
# your computations
self._my_method = value
a = MyClass()
b = a.my_method('do not do this at home')
a is b
# True
a.my_method.split(' ')
# ['do', 'not', 'do', 'this', 'at', 'home']
And today, duck typing will abuse you, forcing you to delegate all kinds of magic methods to the proxied value in the proxy class, until the poor codebase where you want to inject this is satisfied with how those values quack.
This is a minimal implementation of Guillherme's answer that updates the method instead of a separate modifiable parameter:
def classFactory(parent, init_val, target):
class modifierClass(parent):
def __init__(self, init_val):
self.target = target
def __call__(self, *args):
self.target.__init__(*args)
return modifierClass(init_val)
class myClass:
def __init__(self, init_val=''):
self.method = classFactory(init_val.__class__, init_val, self)
This and the original answer both work well for single values, but it seems like lists and dictionaries are returned as empty instead of with the expected values and I am not sure why so help is appreciated here:
If I'm creating a class that needs to store properties, when is it appropriate to use an #property decorator and when should I simply define them in __init__?
The reasons I can think of:
Say I have a class like
class Apple:
def __init__(self):
self.foodType = "fruit"
self.edible = True
self.color = "red"
This works fine. In this case, it's pretty clear to me that I shouldn't write the class as:
class Apple:
#property
def foodType(self):
return "fruit"
#property
def edible(self):
return True
#property
def color(self):
return "red"
But say I have a more complicated class, which has slower methods (say, fetching data over the internet).
I could implement this assigning attributes in __init__:
class Apple:
def __init__(self):
self.wikipedia_url = "https://en.wikipedia.org/wiki/Apple"
self.wikipedia_article_content = requests.get(self.wikipedia_url).text
or I could implement this with #property:
class Apple:
def __init__(self):
self.wikipedia_url = "https://en.wikipedia.org/wiki/Apple"
#property
def wikipedia_article_content(self):
return requests.get(self.wikipedia_url).text
In this case, the latter is about 50,000 times faster to instantiate. However, I could argue that if I were fetching wikipedia_article_content multiple times, the former is faster:
a = Apple()
a.wikipedia_article_content
a.wikipedia_article_content
a.wikipedia_article_content
In which case, the former is ~3 times faster because it has one third the number of requests.
My question
Is the only difference between assigning properties in these two ways the ones I've thought of? What else does #property allow me to do other than save time (in some cases)? For properties that take some time to assign, is there a "right way" to assign them?
Using a property allows for more complex behavior. Such as fetching the article content only when it has changed and only after a certain time period has passed.
Yes, I would suggest using property for those arguments. If you want to make it lazy or cached you can subclass property.
This is just an implementation of a lazy property. It does some operations inside the property and returns the result. This result is saved in the class with another name and each subsequent call on the property just returns the saved result.
class LazyProperty(property):
def __init__(self, *args, **kwargs):
# Let property set everything up
super(LazyProperty, self).__init__(*args, **kwargs)
# We need a name to save the cached result. If the property is called
# "test" save the result as "_test".
self._key = '_{0}'.format(self.fget.__name__)
def __get__(self, obj, owner=None):
# Called on the class not the instance
if obj is None:
return self
# Value is already fetched so just return the stored value
elif self._key in obj.__dict__:
return obj.__dict__[self._key]
# Value is not fetched, so fetch, save and return it
else:
val = self.fget(obj)
obj.__dict__[self._key] = val
return val
This allows you to calculate the value once and then always return it:
class Test:
def __init__(self):
pass
#LazyProperty
def test(self):
print('Doing some very slow stuff.')
return 100
This is how it would work (obviously you need to adapt it for your case):
>>> a = Test()
>>> a._test # The property hasn't been called so there is no result saved yet.
AttributeError: 'Test' object has no attribute '_test'
>>> a.test # First property access will evaluate the code you have in your property
Doing some very slow stuff.
100
>>> a.test # Accessing the property again will give you the saved result
100
>>> a._test # Or access the saved result directly
100
In C, if I want to define a type from a name I could use the preprocessor. For example,
#define DEFINE_STRUCT(name) \
struct My##name##Struct \
{ \
int integerMember##name; \
double doubleMember##name; \
}
And then I could define a concrete struct like so
DEFINE_STRUCT(Useless);
and use the Useless struct like this
struct MyUseslessStruct instance;
So my question is
Is there a way to achieve this in Python?
I have the following class
class ClassName(SQLTable):
items = []
def __init__(self, value):
SQLTable.__init__(self)
# some common code
if value in self.items:
return
self.items.append(value)
For each ClassName the contents of items will be different, so I would like something like
def defineclass(ClassName):
class <Substitute ClassName Here>(SQLTable):
items = []
def __init__(self, value):
SQLTable.__init__(self)
# some common code
if value in self.items:
return
self.items.append(value)
I don't want to repeat the code over and over, I would like to generate it if possible.
You're very close:
def defineclass(ClassName):
class C(SQLTable):
items = []
def __init__(self, value):
SQLTable.__init__(self)
# some common code
if value in self.items:
return
self.items.append(value)
C.__name__ = ClassName
return C
As you can see, you define it using a placeholder name, then assign its __name__ attribute. After that, you return it so you can then use it as you desire in your client code. Remember, a Python class is an object just as much as any other, so you can return it, store it in a variable, put it into a dictionary, or whatever you like once you've defined it.
The __name__ attribute is a convenience, mainly so error messages make sense. You may not actually need to give each class a unique name.
An alternative for this particular use case might be to use subclassing:
class Base(SQLTable):
def __init__(self, value):
SQLTable.__init__(self)
# some common code
if value in self.items:
return
self.items.append(value)
class Thing1(Base): items = []
class Thing2(Base): items = []
By not defining items on the base class, you ensure that you must subclass it and define a per-class items to actually use the class.
kindall's answer is very clear and likely preferable, but there is a built-in function to generate classes: type. When called with one argument, it returns the type of an object. When called with three arguments it generates a new type/class. The arguments are class name, base classes, and the class dict.
def custom_init(self, value):
SqlTable.__init__(self)
if value in self.items:
return
self.items.append(value)
def defineclass(classname):
# __name__ __bases__ __dict__
return type(classname, (SQLTable,), { '__init__': custom_init,
'items': [] })
Say I have a very simple data type:
class SimpleObject:
def __init__(self, property):
self.property = property
def update_property(self, value):
self.property = value
And I a special kind of list to store the data type:
class SimpleList(collections.MutableSequence):
def update_useful_property_of_list(self, value):
self.useful_property_of_list = value
And I store them:
simple1 = SimpleObject(1)
simple2 = SimpleObject(2)
simple_list = SimpleList([simple1, simple2])
Is there any way for the SimpleList object to know when one of the properties of its members changes? For example, how can I get simple_list to execute self.update_useful_property_of_list() when something like this happens:
simple1.update_property(3)
As noted in the comments, you are looking for the Observer design pattern. Simplest, way to do it in your example:
class SimpleObject:
def __init__(self, property, propertyChangeObserver = None):
self.property = property
self.propertyChangeObserver = propertyChangeObserver
def registerPropertyChangeObserver(self, propertyChangeObserver):
self.propertyChangeObserver = propertyChangeObserver
def update_property(self, value):
self.property = value
if self.propertyChangeObserver:
self.propertyChangeObserver.simpleObjectPropertyChanged(self)
and:
class SimpleList(collections.MutableSequence):
def __init__(self, collection):
super(SimpleList, self).__init__(collection)
for e in collection:
e.registerPropertyChangeObserver(self)
def simpleObjectPropertyChanged(self, simpleObject):
pass # react to simpleObject.property being changed
Because you've called your property "property" it's hard to demonstrate low coupling here :) I've called the method simpleObjectPropertyChanged for clarity, but in fact, SimpleList doesn't have to know that it stores SimpleObject instances - it only needs to know that they are observable instances. In a similar manner, SimpleObject doesn't know about SimpleList - it only knows about some class that needs to observe its state (an observer - hence the name of the pattern).
I've read What are Class methods in Python for? but the examples in that post are complex. I am looking for a clear, simple, bare-bones example of a particular use case for classmethods in Python.
Can you name a small, specific example use case where a Python classmethod would be the right tool for the job?
Helper methods for initialization:
class MyStream(object):
#classmethod
def from_file(cls, filepath, ignore_comments=False):
with open(filepath, 'r') as fileobj:
for obj in cls(fileobj, ignore_comments):
yield obj
#classmethod
def from_socket(cls, socket, ignore_comments=False):
raise NotImplemented # Placeholder until implemented
def __init__(self, iterable, ignore_comments=False):
...
Well __new__ is a pretty important classmethod. It's where instances usually come from
so dict() calls dict.__new__ of course, but there is another handy way to make dicts sometimes which is the classmethod dict.fromkeys()
eg.
>>> dict.fromkeys("12345")
{'1': None, '3': None, '2': None, '5': None, '4': None}
I don't know, something like named constructor methods?
class UniqueIdentifier(object):
value = 0
def __init__(self, name):
self.name = name
#classmethod
def produce(cls):
instance = cls(cls.value)
cls.value += 1
return instance
class FunkyUniqueIdentifier(UniqueIdentifier):
#classmethod
def produce(cls):
instance = super(FunkyUniqueIdentifier, cls).produce()
instance.name = "Funky %s" % instance.name
return instance
Usage:
>>> x = UniqueIdentifier.produce()
>>> y = FunkyUniqueIdentifier.produce()
>>> x.name
0
>>> y.name
Funky 1
The biggest reason for using a #classmethod is in an alternate constructor that is intended to be inherited. This can be very useful in polymorphism. An example:
class Shape(object):
# this is an abstract class that is primarily used for inheritance defaults
# here is where you would define classmethods that can be overridden by inherited classes
#classmethod
def from_square(cls, square):
# return a default instance of cls
return cls()
Notice that Shape is an abstract class that defines a classmethod from_square, since Shape is not really defined, it does not really know how to derive itself from a Square so it simply returns a default instance of the class.
Inherited classes are then allowed to define their own versions of this method:
class Square(Shape):
def __init__(self, side=10):
self.side = side
#classmethod
def from_square(cls, square):
return cls(side=square.side)
class Rectangle(Shape):
def __init__(self, length=10, width=10):
self.length = length
self.width = width
#classmethod
def from_square(cls, square):
return cls(length=square.side, width=square.side)
class RightTriangle(Shape):
def __init__(self, a=10, b=10):
self.a = a
self.b = b
self.c = ((a*a) + (b*b))**(.5)
#classmethod
def from_square(cls, square):
return cls(a=square.length, b=square.width)
class Circle(Shape):
def __init__(self, radius=10):
self.radius = radius
#classmethod
def from_square(cls, square):
return cls(radius=square.length/2)
The usage allows you to treat all of these uninstantiated classes polymorphically
square = Square(3)
for polymorphic_class in (Square, Rectangle, RightTriangle, Circle):
this_shape = polymorphic_class.from_square(square)
This is all fine and dandy you might say, but why couldn't I just use as #staticmethod to accomplish this same polymorphic behavior:
class Circle(Shape):
def __init__(self, radius=10):
self.radius = radius
#staticmethod
def from_square(square):
return Circle(radius=square.length/2)
The answer is that you could, but you do not get the benefits of inheritance because Circle has to be called out explicitly in the method. Meaning if I call it from an inherited class without overriding, I would still get Circle every time.
Notice what is gained when I define another shape class that does not really have any custom from_square logic:
class Hexagon(Shape):
def __init__(self, side=10):
self.side = side
# note the absence of classmethod here, this will use from_square it inherits from shape
Here you can leave the #classmethod undefined and it will use the logic from Shape.from_square while retaining who cls is and return the appropriate shape.
square = Square(3)
for polymorphic_class in (Square, Rectangle, RightTriangle, Circle, Hexagon):
this_shape = polymorphic_class.from_square(square)
I find that I most often use #classmethod to associate a piece of code with a class, to avoid creating a global function, for cases where I don't require an instance of the class to use the code.
For example, I might have a data structure which only considers a key valid if it conforms to some pattern. I may want to use this from inside and outside of the class. However, I don't want to create yet another global function:
def foo_key_is_valid(key):
# code for determining validity here
return valid
I'd much rather group this code with the class it's associated with:
class Foo(object):
#classmethod
def is_valid(cls, key):
# code for determining validity here
return valid
def add_key(self, key, val):
if not Foo.is_valid(key):
raise ValueError()
..
# lets me reuse that method without an instance, and signals that
# the code is closely-associated with the Foo class
Foo.is_valid('my key')
Another useful example of classmethod is in extending enumerated types. A classic Enum provides symbolic names which can be used later in the code for readability, grouping, type-safety, etc. This can be extended to add useful features using a classmethod. In the example below, Weekday is an enuerated type for the days of the week. It has been extended using classmethod so that instead of keeping track of the weekday ourselves, the enumerated type can extract the date and return the related enum member.
from enum import Enum
from datetime import date
class Weekday(Enum):
MONDAY = 1
TUESDAY = 2
WEDNESDAY = 3
THURSDAY = 4
FRIDAY = 5
SATURDAY = 6
SUNDAY = 7
#
#classmethod
def from_date(cls, date):
return cls(date.isoweekday())
Weekday.from_date(date.today())
<Weekday.TUESDAY: 2>
Source: https://docs.python.org/3/howto/enum.html
in class MyClass(object):
'''
classdocs
'''
obj=0
x=classmethod
def __init__(self):
'''
Constructor
'''
self.nom='lamaizi'
self.prenom='anas'
self.age=21
self.ville='Casablanca'
if __name__:
ob=MyClass()
print(ob.nom)
print(ob.prenom)
print(ob.age)
print(ob.ville)