Python类变量的范围不是按照文档
这个问题在这里已经有了答案:
做d.kind='cat'
会创建一个名为kind
的新实例属性并将其设置为'cat'
。 而且,这会掩盖类属性。
为了更改类属性,您需要将其设置在类本身而不是实例上:
Dog.kind='cat'
如果你做了instance.attr = "blah"
,你总是设置一个实例属性,即使已经有一个同名的类属性。 通过这样做d.kind = "cat"
创建归于一个实例称为kind
其阴影称为类变量kind
。
你正在设置一个实例属性,屏蔽class属性:
d.kind = 'cat'
如果您将它设置在类上,它将在所有实例中可见:
Dog.kind = 'cat'
您不能通过分配实例名称来设置类属性。 如果可以的话,你将永远无法设置实例属性。
使用vars()
函数来查看区别:
>>> 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
,新属性出现在该实例名称的字典中,并且从那里开始,该实例上的所有查找将返回该属性并且不会落入该类。