2017/1/19
详见代码, Python中, 是否有「所有实例共享的值」这种东西?
定义类
In [1]: class C(object): ...: CLASS_VALUE = 1 ...: In [2]: c1 = C() In [3]: c2 = C() In [4]: c1.CLASS_VALUE, c2.CLASS_VALUE Out[4]: (1, 1) In [5]: c2.CLASS_VALUE = 2 In [6]: c1.CLASS_VALUE, c2.CLASS_VALUE Out[6]: (1, 2)
产品版本:Python2.7.x
操作系统: Linux
类的属性是所有类实例共享的
类实例修改类属性,会发生"copy on write"
In [15]: class C:
...: var = 1
...:
In [16]: c1 = C()
In [17]: c2 = C()
In [18]: c1.var
Out[18]: 1
In [19]: c2.var
Out[19]: 1
In [20]: C.var = 2
In [21]: c1.var
Out[21]: 2
In [22]: c2.var
Out[22]: 2
In [23]: c2.var = 3
In [24]: c2.var
Out[24]: 3
In [25]: c1.var
Out[25]: 2
可以借助一个辅助单例模式的类
class Attr():
attr = {}
def __init__(self):
self.__dict__ = self.attr
class Myclass():
def __init__(self):
self.attr = Attr()
@property
def value(self):
return self.attr.value
@value.setter
def value(self, value):
self.attr.value = value
然后所有的Myclass实例共享一个attr,就有类似的效果。
In [47]: a = Myclass()
In [48]: b = Myclass()
In [49]: a.value = 1
In [50]: b.value
Out[50]: 1
In [51]: b.value = 2
In [52]: a.value, b.value
Out[52]: (2, 2)
Python3
__class__
>>> class C(object):
v=1
>>> c1=C()
>>> c2=C()
>>> c1.v,c2.v
(1, 1)
>>> c2.v=2
>>> c1.v,c2.v
(1, 2)
>>> c2.__class__
<class '__main__.C'>
>>> c2.__class__.v
1
>>> c1.__class__.v
1
>>> c2.__class__.v=99
>>> c1.__class__.v
99
>>>
题主通过c2.CLASS_VALUE = 2赋值的时候实际上是动态的给实例对象c2增加了CLASS_VALUE这个实例属性
所以打印c2.CLASS_VALUE的时候会访问到刚刚动态创建的实例属性。通过打印__dict__就可以看到
而类属性没有改变,通过c1.__class__.CLASS_VALUE还是c2.__class__.CLASS_VALUE都是一样的。想改变类属性的值可以通过类来改变C.CLASS_VALUE = value
In [2]: class C(object): ...: CLASS_VALUE = 1 ...: In [3]: In [3]: c1 = C() In [4]: c2 = C() In [5]: c1.CLASS_VALUE Out[5]: 1 In [6]: c1.__dict__ Out[6]: {} In [7]: C.__dict__ Out[7]: dict_proxy({'CLASS_VALUE': 1, '__dict__': <attribute '__dict__' of 'C' objects>, '__doc__': None, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'C' objects>}) In [8]: c1.CLASS_VALUE = 2 In [9]: c1.__dict__ Out[9]: {'CLASS_VALUE': 2} In [10]: c1.__class__.CLASS_VALUE Out[10]: 1 In [11]: c2.CLASS_VALUE Out[11]: 1 In [12]: C.CLASS_VALUE = 10 In [13]: c1.__class__.CLASS_VALUE Out[13]: 10 In [14]: c2.CLASS_VALUE Out[14]: 10 In [15]: c2.__class__.CLASS_VALUE Out[15]: 10