Skip to main content
 首页 » 编程设计

python之为什么对象中的字典与其他字典没有区别

2025年05月04日17myhome

我有以下 Python 代码:

#!/usr/bin/env python2.6 
 
class container(object): 
    name = 'container' 
    configuration = {'var1': 'var1', 
                     'var2': 'var2'} 
 
if __name__ == "__main__": 
    container1 = container() 
    container2 = container() 
    container2.name = 'container2' 
    container2.configuration['var2'] = 'newvar2' 
 
    print container1.name 
    print container1.configuration['var2'] 

我希望这会打印“container”和“var2”,但对于后者,它会打印“newvar2”

为什么配置变量指向两个对象的同一个字典?我怎样才能解决这个问题?

大多数答案已经解释了 name 和 configuration 是类变量。为什么container2.name的改变不会影响container1.name?

请您参考如下方法:

因为 configuration 是类变量而不是实例变量。解决这个问题应该可以解决您的问题。

class container(object): 
    def __init__(self): 
        self.name = 'container' 
 
        self.configuration = {'var1': 'var1', 
                             'var2': 'var2'} 

这里发生的事情是,configuration 最终位于 containter.__dict__ 中,而不是当您将其设为类变量时位于其实例的字典中。这意味着 c.configuration 只是访问所有实例 c 的 container.__dict__['configuration']。

对于任何类变量,c.foo = x 形式的赋值,在 c.__dict__ 中为 foo 创建一个条目,它隐藏它在 container.__dict__ 中的条目。所以查找将首先返回。如果删除它,则查找将返回以检索类实例。你可以做

c = container() 
c.configuration = x 

然后 c.configuration 就是 x 的内容。但插入键不是赋值,它是对通过现有绑定(bind)访问的现有对象的方法调用。

你可以让 name 成为一个类变量,但如果你想让它从一个实例变为另一个实例,那么它应该是一个实例变量(当然除非你想要一个类范围的默认值) .

所以:

  1. 实例上的赋值(使用=、setattr 或直接插入__dict__)将隐藏类变量。类变量仍然存在。
  2. 对实例的查找(调用方法、访问值)将获取实例属性(如果存在),否则获取类变量。