详解Python中 __get__和__getattr__和__getattribute__的区别
引子
如果以上都搜不到,则抛AttributeError异常. ps.从上面可以看到,dot(.)操作是昂贵的,很多的隐式调用,特别注重性能的话,在高频的循环内,可以考虑绑定给一个临时局部变量. class C(object): def __setattr__(self,name,value): print "__setattr__ called:",value object.__setattr__(self,value) def __getattr__(self,name): print "__getattr__ called:",name def __getattribute__(self,name): print "__getattribute__ called:",name return object.__getattribute__(self,name) c = C() c.x = "foo" print c.__dict__['x'] print c.x
2.object.__getattribute__(self,name) 3.object.__get__(self,instance,owner) class C(object): a = 'abc' def __getattribute__(self,*args,**kwargs): print("__getattribute__() is called") return object.__getattribute__(self,**kwargs) # return "haha" def __getattr__(self,name): print("__getattr__() is called ") return name + " from getattr" def __get__(self,owner): print("__get__() is called",owner) return self def foo(self,x): print(x) class C2(object): d = C() if __name__ == '__main__': c = C() c2 = C2() print(c.a) print(c.zzzzzzzz) c2.d print(c2.d.a) 输出结果是: __getattribute__() is called abc __getattribute__() is called __getattr__() is called zzzzzzzz from getattr __get__() is called <__main__.C2 object at 0x16d2310> <class '__main__.C2'> __get__() is called <__main__.C2 object at 0x16d2310> <class '__main__.C2'> __getattribute__() is called abc 小结: 可以看出,每次通过实例访问属性,都会经过__getattribute__函数。而当属性不存在时,仍然需要访问__getattribute__,不过接着要访问__getattr__。这就好像是一个异常处理函数。 需要注意的是,当使用类访问不存在的变量是,不会经过__getattr__函数。而descriptor不存在此问题,只是把instance标识为none而已。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |