ITEEDU

__getattr__和__getattribute__

#!/usr/bin/env python
class MyClass(object):
    x = 10
    def __getattr__(self, key):
        print '__getattr__'

mc = MyClass()
mc.y                                # __getattr__
print mc.x                       # 10

访问不存在的y属性,会调用到__getattr__

#!/usr/bin/env python
class MyClass(object):
    x = 10
    def __getattr__(self, key):
        print '__getattr__'
    def __getattribute__(self, key):
        print '__getattribute__'
        return super(MyClass, self).__getattribute__(key)

mc = MyClass()
print mc.x                         # __getattribute__
                                           # 10

当__getattr__和__getattribute__同时存在,不管访问存在或是不存在的属性,都会先调用__getattribute__。 所以__getattr__永远不会被调到。

另外,在__getattribute__的函数中,不能直接访问self的属性(会导致再次调用__getattribute__,然后死循环), 应该使用super(obj, self).__getattribute__(key),类似这样的方法。对于class的属性(例如这里的x),也可以 直接用MyClass.x来访问。

#!/usr/bin/env python
class MyClass(object):
    x = 10
    def __getattr__(self, key):
        print '__getattr__'
    def __getattribute__(self, key):
        print '__getattribute__'
        return super(MyClass, self).__getattribute__(key)

mc = MyClass()
mc.x = 20                 # __getattribute__
print mc.x                 # 20

同样,__getattribute__也会先访问instance的属性。