为什么对象中的字典与其他字典没有不同?

发布于 2024-10-02 05:33:58 字数 598 浏览 2 评论 0原文

我有以下 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甜妞爱困 2024-10-09 05:33:58

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

class container(object):
    def __init__(self):
        self.name = 'container'

        self.configuration = {'var1': 'var1',
                             'var2': 'var2'}

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

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

c = container()
c.configuration = x

,然后 c.configuration 将是 x 的任何内容。但插入键并不是赋值,而是对通过现有绑定访问的现有对象的方法调用。

您可以将 name 设为类变量,但如果您希望它从一个实例更改为另一个实例,那么它应该是一个实例变量(当然,除非您想要一个类范围的默认值)。

so:

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

Because configuration is a class variable and not an instance variable. Fixing this should fix your problem.

class container(object):
    def __init__(self):
        self.name = 'container'

        self.configuration = {'var1': 'var1',
                             'var2': 'var2'}

What's going on here is that configuration ends up living in containter.__dict__ instead of in the dictionaries of its instances when you make it a class variable. This means that c.configuration is just accessing container.__dict__['configuration'] for all instances c.

For any class variable, an assignment of the form c.foo = x, creates an entry for foo in c.__dict__ which shadows its entry in container.__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 do

c = container()
c.configuration = x

and then c.configuration would be whatever x 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:

  1. An assignment (using =, setattr or directly inserting in __dict__) on an instance will shadow a class variable. The class variable is still there.
  2. A lookup (calling a method, accessing the value) on an instance will grab an instance attribute if it exists and a class variable otherwise.
就此别过 2024-10-09 05:33:58

因为 nameconfiguration 是容器类的类或静态成员,并且它们为容器的所有实例共享。使用 self.name, self.configuration 作为实例变量:

class container(object):
   def __init__(self):
      self.name = "container"
      self.configuration = {}

Because name and configuration 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:

class container(object):
   def __init__(self):
      self.name = "container"
      self.configuration = {}
极致的悲 2024-10-09 05:33:58
self.name = 'container'
self.configuration = {'var1': 'var1',
                      'var2': 'var2'}

如果它们是类变量,则在 init() 中。

self.name = 'container'
self.configuration = {'var1': 'var1',
                      'var2': 'var2'}

In init() if they are the class variables.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文