我做了一个例子,试图说服你采取第二种方法,但是我自己也感到困惑了...
>>> class Foo():
... LABELS = ('One','Two','Three')
...
>>> Foo.LABELS
('One', 'Two', 'Three')
>>> Foo.LABELS = (1,2,3)
>>> Foo.LABELS
(1, 2, 3)
>>> f = Foo()
>>> g = Foo()
>>> f.LABELS = ('a','b','c')
>>> g.LABELS
(1, 2, 3)
>>> Foo.LABELS
(1, 2, 3)
>>> f.LABELS
('a', 'b', 'c')
“发生了什么?”我心里想着。然后我意识到行为取决于对象ID...
>>> id(Foo.LABELS)
4562309280
>>> id(g.LABELS)
4562309280
>>> id(f.LABELS)
4562068336
>>> ('a','b','c') is ('a','b','c')
False
>>> Foo.LABELS = (4,5,6)
>>> g.LABELS
(4, 5, 6)
>>> f.LABELS
('a', 'b', 'c')
>>> id(Foo.LABELS)
4562309200
>>> id(g.LABELS)
4562309200
>>> id(f.LABELS)
4562068336
那么,回到我的最初答案:
除非您不关心变量被重新分配的情况,否则不要采用第一种方法,因为您将得到的结果与您的期望不符。第一种方法使变量属于类,第二种方法使变量属于实例——但是如果在第一种情况下有人重新分配了变量,您将获得一些非常奇怪的结果。
推论——如果您的类方法仅引用类的变量(即 Foo.LABELS
),那么您显然会得到您所期望的结果,但是如果某人以不同的方式重复使用了您的代码,那么谁知道他们会得到什么?
推论#2——在Python中没有办法强制实现引用不可变性。因此,您真的应该采用第二种方法。