python类变量范围不符合文档

Python class variables scope not as per documentation

本问题已经有最佳答案,请猛点这里访问。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
>>> 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'

我错过什么了吗?


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

要更改class属性,需要在类本身而不是实例上设置它:

1
Dog.kind='cat'


如果执行instance.attr ="blah",则始终设置实例属性,即使已经存在同名的类属性。通过执行d.kind ="cat"操作,您创建了一个名为kind的属性化实例,它隐藏了名为kind的类变量。


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

1
d.kind = 'cat'

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

1
Dog.kind = 'cat'

不能通过为实例上的名称赋值来设置类属性。如果可以,就永远无法设置实例属性。

使用vars()功能查看区别:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
>>> 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__': , 'kind': 'canine', '__weakref__': , '__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赋值,新属性将出现在该实例的名称字典中,从那里开始,该实例上的所有查找都将返回该属性,而不属于类。