class Foo(object):
bar = 1
def __init__(self):
... etc.
和
class Foo(object):
def __init__(self):
... etc.
Foo.bar = 1
之间的差异在这两种情况下,bar
是类的属性,它是同为类的所有实例,对不对?
class Foo(object):
bar = 1
def __init__(self):
... etc.
和
class Foo(object):
def __init__(self):
... etc.
Foo.bar = 1
之间的差异在这两种情况下,bar
是类的属性,它是同为类的所有实例,对不对?
我想说的是,唯一的区别是,在第二种情况下,Foo.bar
而不是以前的,而在第一种情况下创建类对象时已经可以执行Foo.bar = 1
声明存在。
这可能没有在你的代码产生任何影响小的差异(除非有一些代码,需要Foo.bar
它在第二种情况下是可用之前)。不过,我会说第一个选项在可读性方面更好,因为您不必向下滚动以了解您班级的属性,它们已经在那里了。
如果你正在编写自己的代码,请与:
class Foo(object):
bar = 1
becase的这个版本:
class Foo(object):
pass
Foo.bar = 1
即使它是合法的
如果您尝试访问bar
属性的创建之前,您可能有问题:
>>> 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
其他我并不认为有很多不同之处。
两个版本是相同的(见这个答案最终的测试成绩单),但要注意在两种情况下是:(a)为bar
为Foo
所有实例相同。
在创建一个实例的时刻,读取所述实例bar
将读取Foo
分配到Foo.bar
的值,将反映在直到instance.bar
被分配给该实例。在分配的那个时刻,实例获取自己的__dict__
条目,它完全独立于该类。
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'
-1显然是错误的:“Foo”的实例不是“bar”的副本 - 它们访问类属性。当设置一个实例属性时,它将获得它自己的属性。见我的答案在http://stackoverflow.com/questions/9302789/changing-variables-in-multiple-python-instances/9304924#9304924 – jsbueno 2012-02-16 10:52:31
@jsbueno:证明这一点。该行为看起来就像每个实例获取类对象中的值的副本(这是指向对象的指针)。 – Marcin 2012-02-16 11:04:26
@jsbueno:我已经添加了自己的证据,因为您链接的答案实际上并没有任何证据表明您的立场。 – Marcin 2012-02-16 11:12:09
感谢,是有意义的。 – mcepl 2012-02-16 10:55:53