Today I read the white paper super .
In which he mentioned multiple inheritance, will be determined by the __mro__ attribute for the class.
Therefore, I experimented a bit, but its result surprised me.
# CODE PART class GrandFather(object): def p(self): print "I'm old." class Father(GrandFather): def p(self): print "I'm male." class Mother(object): def p(self): print "I'm female." class Son(Father, Mother): def p(self): print "busy, busy, crwaling. "
The following is part of the official document mentioned above, it says:
super(type[, object-or-type]) Return a proxy object that delegates method calls to a parent or sibling class of type. This is useful for accessing inherited methods that have been overridden in a class. The search order is same as that used by getattr() except that the type itself is skipped. The __mro__ attribute of the type lists the method resolution search order used by both getattr() and super(). The attribute is dynamic and can change whenever the inheritance hierarchy is updated. If the second argument is an object, isinstance(obj, type) must be true.
By combining this document and the result of my experiment. The most confusing part is that when called with super(GrandFather, s).p() it calls p() from Mother , but Mother not in GrandFather __mro__ , and it is in very low order Son __mro__ .
After a little reflection. I received a plausible explanation that indicates the incompleteness or lack of an official document:
That is, when used with super(type, instance) , the super function searches from the __mro__ class attribute from which your instance is created, but not the __mro__ type attribute that you passed to super , even if it satisfies the isinstance(instance, type) condition.
So what happened when you typed super(Class, instance) :
- Python checks to see if
isinstance(instance, Class) is True. - Python will find the
__class__ instance attribute,
get the instance.__class__ __mro__ . - Python will find the
class index you passed to super in the __mro__ tuple in step 2. - Python adds the index of step 3 to 1, uses it to get the corresponding class in the
__mro__ tuple in step 2, and returns the super-delegate of this corresponding class. - If the index in step 4 exceeds the length of
__mro__ for step 2, the delegate of the last class is __mro__ to __mro__ for step 2, which is the class object .
As far as I understand?
If I'm wrong, then what is the mechanism that super interacts with type __mro__ ?
If I am right, how should I raise the question of modifying a python whitepaper?
Because I think that the current version about this element can be misleading.
PS: This test was performed by Python 2.7.6 within IPython 3.2.1 .