获取/设置 属性---从一段代码讲起
>>> class MyClass(object):
... attr="this is a test"
...
>>> obj=MyClass()
>>> obj.attr
'this is a test'
>>> MyClass.attr="new class value"
>>> obj.attr #1
'new class value'
>>> obj.attr="new obj value" #2
>>> MyClass.attr
'new class value'
在上面的这段代码中,
(1)行#1 表明,从obj可以获得 MyClass的属性。
(2)行#2 表明,对obj.attr赋值,并不会改变MyClass中的attr属性。
这是为什么呢?答案如下:
(1)获取obj.attr属性时,先在obj的__dict__中找,如果没找到的话,会在MyClass的__dict__中找,再找不到的话,会顺着MyClass的基类一直往上找。如果还没找到的话,__getattr__ will be called when an attribute lookup has not found the attribute in the
usual places (i.e. it is not an instance attribute nor is it found in
the class tree for self)
(2)在设置obj.attr时,并不会沿着类树回溯,而只是查找obj.__dict__,如果有的话,则赋新值,如果没有的话,则在字典中增加一项。
(3)另外,在设置obj.attr的值时,和__getattr__优先级排在最后不同的是,如果定义了__setattr__,那么它就会被优先调用: it will be called when an attribute assignment is attempted. This is called instead of the normal mechanism (i.e. store the value in the instance dictionary)
下面这段代码说明了这一点:
>>> class MyClass:
... def __setattr__(self,name,value):
... self.__dict__[name]=value
... print 'setattr'
...
>>> a=MyClass()
>>> a.b=3
setattr
>>> print a.__dict__
{'b': 4}
>>> a.b=4 #即使a.__dict__里面已经有了b,还是调用了__setattr__
setattr