When I have this class, the variable 'value' is class variable.
class Hello:
value = 10
def __init__(self):
print 'init'
I have an object 'h' and I could get the same value of '10' both for Hello.value and h.value.
h = 开发者_运维百科Hello()
print Hello.value
print h.value
When I run this command,
h.value = 20
I get value '10', and '20', when I run them.
print Hello.value
print h.value
Why is this?
- Q1 : Why 'print h.value' prints out the value of Hello.value, not raise an error?
- Q2 : Does h.value = 20 introduce a new variable similar to 'self.value = 20'?
- Q3 : Is there a way to prevent creating an instance variable (or prevent running code 'h.value = 20')?
That's how attribute lookup works in Python:
If an attribute can't be found in the dictionary of an instance, it is looked up in the dictionary of its class, and if it can't be found there, also in the dictionaries of the base classes.
If you assign to an instance attribute, this will always only affect the instance -- i.e. update the attribute if it already exists in the instance or create it in the instance's dictionary if not.
If you don't like this behaviour, you can overwrite the __setattr__()
method to do whatever you like -- for example throwing an error if you don't want to allow the creation of instance attributes. The latter can also be achieved by adding __slots__ = []
to the class.
If Python looks up o.attr
, it first checks the object instance, then its class, then the base class, and so on. It does so both for methods and data attributes (i.e. there is no distinction between data and code attributes).
On assignment, the value always gets assigned to the instance. So
A1. Because it falls back to the class (which it must, because methods wouldn't work otherwise)
A2. Yes, it does.
A3. You can define a
__setattr__
method that raises an exception.
精彩评论