首页  >  问答  >  正文

Python 定义类时, 为何该值不是所有实例共享的 ?

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)                            

上下文环境

尝试解决

怪我咯怪我咯2765 天前426

全部回复(4)我来回复

  • 大家讲道理

    大家讲道理2017-04-18 10:17:36

    题主通过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
    

    回复
    0
  • PHPz

    PHPz2017-04-18 10:17:36

    Python3

    __class__

    雷雷

    回复
    0
  • 阿神

    阿神2017-04-18 10:17:36

    可以借助一个辅助单例模式的类

    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)                   

    回复
    0
  • 天蓬老师

    天蓬老师2017-04-18 10:17:36

    • 类的属性是所有类实例共享的

    • 类实例修改类属性,会发生"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

    回复
    0
  • 取消回复