python:__getattr__() 和 __getattribute__()

關於__getattr__

object.__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 __getattr__() 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.

關於__get__getattribute__

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).

Note This method may still be bypassed when looking up special methods as the result of implicit invocation via language syntax or built-in functions.

例子:

__getattr__示例:
class Test(object):
    def __init__(self,name):
        self.name = name
    def __getattr__(self, value):
        if value == 'address':
            return 'China'

if __name__=="__main__":
    test = Test('letian')
    print test.name
    print test.address
    test.address = 'Anhui'
    print test.address
運行結果:
letian
China
Anhui
若是是調用了一個類中未定義的方法,則__getattr__也要返回一個方法,例如:
class Test(object):
    def __init__(self,name):
        self.name = name
    def __getattr__(self, value):
        return len

if __name__=="__main__":
    test = Test('letian')
    print test.getlength('letian')
運行結果:
6
__getattribute__示例:
class Test(object):
    def __init__(self,name):
        self.name = name
    def __getattribute__(self, value):
        if value == 'address':
            return 'China'
        

if __name__=="__main__":
    test = Test('letian')
    print test.name
    print test.address
    test.address = 'Anhui'
    print test.address
運行結果:
None
China
China

參考:

Data model: http://docs.python.org/2/reference/datamodel.html
Overwriting __getattr__ makes help(…) fail with TypeError: http://stackoverflow.com/questions/5157746/overwriting-getattr-makes-help-fail-with-typeerror
相關文章
相關標籤/搜索