Reputation: 2786
Is there a difference between
class Foo(object):
bar = 1
def __init__(self):
... etc.
and
class Foo(object):
def __init__(self):
... etc.
Foo.bar = 1
In both cases bar
is a property of the class and it is same for all instances of the class, right?
Upvotes: 4
Views: 277
Reputation: 49886
Both versions are the same (see transcript of tests at end of this answer), but note that (a) in neither case is bar
the same for all instances of Foo
.
At the moment an instance is created, reading bar
on the instance will read the value in Foo
, and assignments to Foo.bar
will be reflected in the instance until instance.bar
is assigned to. At that moment of assignment, the instance gets its own __dict__
entry, which is entirely independant of the class.
In [62]: class Foo: pass
In [63]: Foo.bar = 1
In [64]: Foo.bar
Out[64]: 1
In [65]: f = Foo()
In [66]: f.bar
Out[66]: 1
In [67]: f.bar +=1
In [68]: f.bar
Out[68]: 2
In [69]: Foo.bar
Out[69]: 1
In [70]: Foo.bar +=3
In [71]: Foo.bar
Out[71]: 4
In [72]: g = Foo()
In [73]: g.bar
Out[73]: 4
In [74]: class Qux: bar = 1
In [75]: Qux.bar
Out[75]: 1
In [76]: q = Qux()
In [77]: q.bar
Out[77]: 1
In [78]: q.bar+=1
In [79]: q.bar
Out[79]: 2
In [80]: Qux.bar
Out[80]: 1
In [81]: Qux.bar +=1
In [82]: r = Qux()
In [83]: r.bar
Out[83]: 2
In [84]: q.bar
Out[84]: 2
In [85]: s = Qux()
In [87]: s.__dict__
Out[87]: {}
In [88]: q.__dict__
Out[88]: {'bar': 2}
In [89]: Qux.bar = 'foo'
In [90]: Qux.bar
Out[90]: 'foo'
In [91]: s.bar
Out[91]: 'foo'
Upvotes: -1
Reputation: 29312
If you're writing your own code, go with:
class Foo(object):
bar = 1
Becase this version:
class Foo(object):
pass
Foo.bar = 1
Even though it's legit
You might have problems if you try to access the bar
attribute before its been created:
>>> class Foo:
... pass
...
>>> f = Foo()
>>> f.bar
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'bar'
>>> Foo.bar = 1
>>> f.bar # but hey, now you're ok!
1
Other than that I don't see many differences.
Upvotes: 4
Reputation: 40424
I'd say that the only difference is that in the second case, Foo.bar
doesn't exist until the Foo.bar = 1
statement is executed while in the first case is already available when the class object is created.
That's probably a small difference without any effect in your code (unless there is some code that requires Foo.bar
before it's available in the second case). However, I'd say that the first option is better in terms of readability since you don't have to scroll down to know the attributes for your class, they're already there.
Upvotes: 4