Python class variables scope not as per documentation
This question already has an answer here:
Doing d.kind='cat'
creates a new instance attribute named kind
and sets it to 'cat'
. Moreover, this overshadows the class attribute.
In order to change the class attribute, you need to set it on the class itself and not an instance:
Dog.kind='cat'
If you do instance.attr = "blah"
, you always set an instance attribute, even if there is already a class attribute of the same name. By doing d.kind = "cat"
you created an instance attributed called kind
which shadows the class variable called kind
.
You are setting an instance attribute, masking the class attribute:
d.kind = 'cat'
If you set it on the class instead it'll be visible on all instances:
Dog.kind = 'cat'
You cannot set class attributes by assigning to the name on instances. If you could, you would never be able to set instance attributes.
Use the vars()
function to see the difference:
>>> 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'
The vars()
function reveals the attributes available on both the class and one of the instances. By assigning to d.kind
, the new attribute appears in the dictionary of names for that instance, and from there on out all lookups on that instance will return that attribute and not fall through to the class.
上一篇: 类变量的行为
下一篇: Python类变量的范围不是按照文档