python __getattribute__ 的优先级问题

The way __getattribute__() works needs to be covered, as it was implemented to behave in a very specific way. Thus it is very important to recognize this ordering:

  • Class attributes

  • Data descriptors

  • Instance attributes

  • Non-data descriptors

  • Defaulting to __getattr__()

A descriptor is a class attribute, so all class attributes have the highest priority.……这个是在core python programming 13.16节摘录下来的,这个是让我很困惑的地方;原因在于Class attributes 与Instance attributes的优先级问题;看下面的例子:



针对没有描述符的情况下,这个查找顺序应该是先查找的t.__dict__,然后才查找的Test.__dict__,总结起来就是先在obj.__dict__中查找,然后再查找obj.__class__.__dict__;

 

 

有数据描述符的情况下:

结果一幕了然,由于a是一个类属性,同时是一个数据描述符,__getattribute__在查找时应该是先访问了Test1.__dict__,如果存在且是数据描述符,则调用描述符的__get__or__set__,翻译起来就是:先查找type(obj).__dict__,如果属性存在并且是数据描述符,则执行data descriptor的__get__or__set__;

结论:属性/方法查找顺序

 

1.如果attr是一个Python自动产生的属性,找到!(优先级非常高!)

2.查找obj.__class__.__dict__,如果attr存在并且是data descriptor,返回data descriptor的__get__方法的结果,如果没有继续在obj.__class__的父类以及祖先类中寻找data descriptor

3.在obj.__dict__中查找,这一步分两种情况,第一种情况是obj是一个普通实例,找到就直接返回,找不到进行下一步。第二种情况是obj是一个类,依次在obj和它的父类、祖先类的__dict__中查找,如果找到一个descriptor就返回descriptor的__get__方法的结果,否则直接返回attr。如果没有找到,进行下一步。

4.在obj.__class__.__dict__中查找,如果找到了一个descriptor(插一句:这里的descriptor一定是non-data descriptor,如果它是data descriptor,第二步就找到它了)descriptor的__get__方法的结果。如果找到一个普通属性,直接返回属性值。如果没找到,进行下一步。

5.Defaulting to __getattr__()

6.raise AttributeError

 

 

引用:

http://onlypython.group.iteye.com/group/wiki/1362-python-39-s-descriptor

你可能感兴趣的:(attribute)