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

 不必要有人假装很懂我_987 发布于 2022-10-25 17:35

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

尝试解决

4 个回答
    • 类的属性是所有类实例共享的

    • 类实例修改类属性,会发生"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
    2022-11-12 01:41 回答
  • 可以借助一个辅助单例模式的类

    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)                   
    2022-11-12 01:41 回答
  • 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
    >>> 
    2022-11-12 01:41 回答
  • 题主通过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
    
    2022-11-12 01:41 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有