The way I usually declare a class variable to be used in instances in Python is the following:
class MyClass(object):
def __init__(self):
self.a_member = 0
my_object = MyClass()
my_object.a_member # evaluates to 0
But the following also works. Is it bad practice? If so, why?
class MyClass(object):
a_member = 0
my_object = MyClass()
my_object.a_member # also evaluates to 0
The second method is used all over Zope, but I haven’t seen it anywhere else. Why is that?
Edit: as a response to sr2222’s answer. I understand that the two are essentially different. However, if the class is only ever used to instantiate objects, the two will work he same way. So is it bad to use a class variable as an instance variable? It feels like it would be but I can’t explain why.
The question is whether this is an attribute of the class itself or of a particular object. If the whole class of things has a certain attribute (possibly with minor exceptions), then by all means, assign an attribute onto the class. If some strange objects, or subclasses differ in this attribute, they can override it as necessary. Also, this is more memory-efficient than assigning an essentially constant attribute onto every object; only the class’s
__dict__has a single entry for that attribute, and the__dict__of each object may remain empty (at least for that particular attribute).In short, both of your examples are quite idiomatic code, but they mean somewhat different things, both at the machine level, and at the human semantic level.
Let me explain this:
On line two, you’re setting a “class attribute”. This is litterally an attribute of the object named “MyClass”. It is stored as
MyClass.__dict__['a_member'] = 'a'. On later lines, you’re setting the object attributeo.a_memberto be. This is completely equivalent too.__dict__['a_member'] = 'b'. You can see that this has nothing to do with the separate dictionary ofp.__dict__. When accessinga_memberof p, it is not found in the object dictionary, and deferred up to its class dictionary:MyClass.a_member. This is why modifying the attributes ofodo not affect the attributes ofp, because it doesn’t affect the attributes ofMyClass.