飘逸的python - __get__ vs __getattr__ vs __getattribute__以及属性的搜索策略
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了飘逸的python - __get__ vs __getattr__ vs __getattribute__以及属性的搜索策略相关的知识,希望对你有一定的参考价值。
差别:
__getattribute__:是无条件被调用.对不论什么对象的属性訪问时,都会隐式的调用__getattribute__方法,比方调用t.__dict__,事实上运行了t.__getattribute__("__dict__")函数.所以假设我们在重载__getattribute__中又调用__dict__的话,会无限递归,用object大神来避免,即object.__getattribute__(self, name).
__getattr__:仅仅有__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__以及属性的搜索策略的主要内容,如果未能解决你的问题,请参考以下文章
飘逸的python - 几行代码实现unix管道风格的函数调用
Python进阶-----描述符(__get__(),__set__(),__delete__())
了解 __get__ 和 __set__ 以及 Python 描述符