【问题标题】:Python class variables scope not as per documentation [duplicate]Python类变量范围不符合文档[重复]
【发布时间】:2015-04-26 13:54:36
【问题描述】:

根据documentation:“一般来说,实例变量用于每个实例唯一的数据,类变量用于类的所有实例共享的属性和方法”

>>> class Dog:
...   kind='canine'
...   
...   def __init__(self, name):
...     self.name = name
... 
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.name
'Fido'
>>> e.name
'Buddy'
>>> d.kind
'canine'
>>> e.kind
'canine'
>>> d.kind='cat' # changed supposedly shared variable to cat
>>> d.kind # OK here
'cat'
>>> e.kind # Not expected output (should be cat as per documentation)
'canine'

我错过了什么吗?

【问题讨论】:

  • 您已经为对象更改了它,为一个对象更改不会反映在所有对象中。对象是类的一个实例
  • 这可能不是“重复”标记的最佳选择,但这个问题确实经常出现。

标签: python class variables scope shared


【解决方案1】:

执行d.kind='cat' 会创建一个名为kind 的新实例属性并将其设置为'cat'。此外,这掩盖了类属性。

为了改变类属性,你需要在类本身而不是实例上设置它:

Dog.kind='cat'

【讨论】:

  • 谢谢。又短又甜!
【解决方案2】:

如果你做instance.attr = "blah",你总是设置一个实例属性,即使已经有一个同名的类属性。通过执行d.kind = "cat",您创建了一个名为kind 的实例属性,它隐藏了名为kind 的类变量。

【讨论】:

    【解决方案3】:

    您正在设置实例属性,屏蔽类属性:

    d.kind = 'cat'
    

    如果你在类上设置它,它将在所有实例上可见:

    Dog.kind = 'cat'
    

    您不能通过分配给实例上的名称来设置类属性。如果可以,您将永远无法设置实例属性。

    使用vars() function 来查看区别:

    >>> class Dog:
    ...     kind = 'canine'
    ...     def __init__(self, name):
    ...         self.name = name
    ... 
    >>> d = Dog('Fido')
    >>> e = Dog('Buddy')
    >>> vars(d)
    {'name': 'Fido'}
    >>> 'kind' in vars(d)
    False
    >>> vars(Dog)
    mappingproxy({'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Dog' objects>, 'kind': 'canine', '__weakref__': <attribute '__weakref__' of 'Dog' objects>, '__doc__': None, '__init__': <function Dog.__init__ at 0x10084bbf8>})
    >>> 'kind' in vars(Dog)
    True
    >>> d.kind
    'canine'
    >>> d.kind = 'cat'
    >>> d.kind
    'cat'
    >>> vars(d)
    {'name': 'Fido', 'kind': 'cat'}
    >>> Dog.kind
    'canine'
    

    vars() 函数揭示了类和其中一个实例上可用的属性。通过分配给d.kind,新属性将出现在该实例的名称字典中,从那里开始对该实例的所有查找都将返回该属性,而不是落入该类。

    【讨论】:

      猜你喜欢
      • 2013-04-11
      • 2020-08-14
      • 2017-02-13
      • 2014-04-18
      • 2011-08-24
      • 1970-01-01
      • 2015-08-07
      • 2011-07-10
      • 2010-12-07
      相关资源
      最近更新 更多