Python __getattr__

Python Code:

######################################

class D(object):
    def __init__(self):
        self.default = 0.0
        self.test = 20
        self.test2 = 21
    def __getattribute__(self, name):
        try:
            if name == 'test':
                print ("__getattribute__ name = %s" % name)
                return self.test        #This will default call same function "__getattribute__", can fix by object
            else:
                print ("__getattribute__ name = %s" % name)
                return object.__getattribute__(self, name)
        except AttributeError:
            print "getattribute error"
            raise
    def __getattr__(self, name):
        print ("__getattr__ name = %s" % name)
        print ("self.default=%s" % self.default)
        return self.default
if __name__ == "__main__":
    d = D()
    #print d.test       #This will caused recurison error because it call the same function, your getattribute
    print d.test2
    print d.ts           #When "__getattribute__" raise error, it will call in "__getattr__".

######################################

輸出:
>>> 
__getattribute__ name = test2
21
__getattribute__ name = ts
getattribute error
__getattr__ name = ts
__getattribute__ name = default
self.default=0.0
__getattribute__ name = default
0.0

######################################

1. 任何調用類的屬性行爲都將從"__getattribute__"開始調用。

2. 在"__getattribute__"中調用該函數自身屬性,將會致使無限循環。應該借用object對象再調用其自己。

3. "__getattr__"將會在尋找不到合適的函數或者屬性時做爲默認被調用到。

Python doc:

__getattr__( self, name)

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). name is the attribute name. This method should return the (computed) attribute value or raise an AttributeError exception.
Note that if the attribute is found through the normal mechanism, __getattr__() is not called. (This is an intentional asymmetry between __getattr__() and __setattr__().) This is done both for efficiency reasons and because otherwise __setattr__() would have no way to access other attributes of the instance. Note that at least for instance variables, you can fake total control by not inserting any values in the instance attribute dictionary (but instead inserting them in another object). See the __getattribute__() method below for a way to actually get total control in new-style classes.
     object.__getattribute__(self, name)? 

Called unconditionally to implement attribute accesses for instances of the class. If the class also   defines __getattr__(), the latter will not be called unless __getattribute__() either calls it explicitly or raises an AttributeError. This method should return the (computed) attribute value or raise an AttributeError exception. In order to avoid infinite recursion in this method, its implementation should always call the base class method with the same name to access any attributes it needs, for example, object.__getattribute__(self, name).

4. 一般來講,若是腳本即包含"__getattribute__" ,又包含"__getattr__"的時候,是不會調用到"__getattr__"的,但從上面的例子能夠看出,若是"__getattribute__"報錯,一樣會自動調用到"__getattr__"。
相關文章
相關標籤/搜索