为什么对象中的字典与其他字典没有不同?
我有以下 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”
为什么两个对象的配置变量指向相同的字典?我该如何解决这个问题?
大多数答案已经解释了名称和配置是类变量。为什么container2.name的改变不会影响container1.name?
I have the following Python code:
#!/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']
I expect this to print 'container' and 'var2', but for the latter it prints 'newvar2' instead
Why does the configuration variable point to the same dictionary for both objects? How can I fix this?
Most answers are already explaining that name and configuration are class variables. Why does the change of container2.name not influence container1.name?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
因为
configuration
是一个类变量而不是实例变量。解决这个问题应该可以解决您的问题。这里发生的事情是,当您将配置设置为类变量时,配置最终会存在于containter.__dict__ 中,而不是存在于其实例的字典中。这意味着
c.configuration
只是访问所有实例c
的container.__dict__['configuration']
。对于任何类变量,
c.foo = x
形式的赋值会在c.__dict__
中为foo
创建一个条目,从而隐藏其条目在container.__dict__
中。因此,查找将首先返回该值。如果删除它,则查找将返回以检索类实例。你可以这样做,然后
c.configuration
将是x
的任何内容。但插入键并不是赋值,而是对通过现有绑定访问的现有对象的方法调用。您可以将
name
设为类变量,但如果您希望它从一个实例更改为另一个实例,那么它应该是一个实例变量(当然,除非您想要一个类范围的默认值)。so:
=
、setattr
或直接插入__dict__
)将隐藏类变量。类变量仍然存在。Because
configuration
is a class variable and not an instance variable. Fixing this should fix your problem.What's going on here is that
configuration
ends up living incontainter.__dict__
instead of in the dictionaries of its instances when you make it a class variable. This means thatc.configuration
is just accessingcontainer.__dict__['configuration']
for all instancesc
.For any class variable, an assignment of the form
c.foo = x
, creates an entry forfoo
inc.__dict__
which shadows its entry incontainer.__dict__
. So a lookup will return that first. If you delete it, then a lookup will go back to retrieving the class instance. You could doand then
c.configuration
would be whateverx
was. But inserting a key isn't an assignment, it's a method call on an existing object accessed through an existing binding.You could get away with making
name
a class variable but if you want it to change from one instance to another then it should be an instance variable (unless you want a class wide default of course).so:
=
,setattr
or directly inserting in__dict__
) on an instance will shadow a class variable. The class variable is still there.因为
name
和configuration
是容器类的类或静态成员,并且它们为容器的所有实例共享。使用 self.name, self.configuration 作为实例变量:Because
name
andconfiguration
are class or static members of the container class and they are shared for all the instances of container. Use self.name, self.configuration for instance variables:如果它们是类变量,则在 init() 中。
In init() if they are the class variables.