首页 > 代码库 > python中__get__ vs __getattr__ vs __getattribute__以及属性的搜索策略
python中__get__ vs __getattr__ vs __getattribute__以及属性的搜索策略
其中,__getattribute__是无条件被调用.
对任何对象的属性访问时,都会隐式的调用__getattribute__方法,比如调用t.__dict__,其实执行了t.__getattribute__("__dict__")函数.所以如果我们在重载__getattribute__中又调用__dict__的话,会无限递归,用object大神来避免,即object.__getattribute__(self, name).
只有__getattribute__找不到的时候,才会调用__getattr__.
而__get__是descriptor.
假设我们有个类A,其中a是A的实例
a.x时发生了什么?属性的lookup顺序如下:
ps.从上面可以看到,dot(.)操作是昂贵的,很多的隐式调用,特别注重性能的话,在高频的循环内,可以考虑绑定给一个临时局部变量.
对任何对象的属性访问时,都会隐式的调用__getattribute__方法,比如调用t.__dict__,其实执行了t.__getattribute__("__dict__")函数.所以如果我们在重载__getattribute__中又调用__dict__的话,会无限递归,用object大神来避免,即object.__getattribute__(self, name).
只有__getattribute__找不到的时候,才会调用__getattr__.
而__get__是descriptor.
假设我们有个类A,其中a是A的实例
a.x时发生了什么?属性的lookup顺序如下:
- 如果重载了__getattribute__,则调用.
- a.__dict__, 实例中是不允许有descriptor的,所以不会遇到descriptor
- A.__dict__, 也即a.__class__.__dict__ .如果遇到了descriptor,优先调用descriptor.
- 沿着继承链搜索父类.搜索a.__class__.__bases__中的所有__dict__. 如果有多重继承且是菱形继承的情况,按MRO(Method Resolution Order)顺序搜索.
ps.从上面可以看到,dot(.)操作是昂贵的,很多的隐式调用,特别注重性能的话,在高频的循环内,可以考虑绑定给一个临时局部变量.
下面给个代码片段大家自己去把玩探索.
class C(object): def __setattr__(self, name, value): print "__setattr__ called:", name, value object.__setattr__(self, name, 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
python中__get__ vs __getattr__ vs __getattribute__以及属性的搜索策略
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。