Python, всё, что вам надо знать про функцию 'super' и Method Resolution Order
цитата
The super built-in function was introduced way back in Python 2.2. The super function will return a proxy object that will delegate method calls to a parent or sibling class of type. If that was a little unclear, what it allows you to do is access inherited methods that have been overridden in a class
...
class MyParentClass(object):
def __init__(self):
pass
class SubClass(MyParentClass):
def __init__(self):
MyParentClass.__init__(self)
class SubClass(MyParentClass):
def __init__(self):
super(SubClass, self).__init__()
Python 3 simplified this a bit. Let’s take a look:
class MyParentClass():
def __init__(self):
pass
class SubClass(MyParentClass):
def __init__(self):
super()
...
super knows how to interpret the MRO and it stores this information in the
following magic propertie:
__thisclass__ and
__self_class__.
Let’s look at an example:
class Base():
def __init__(self):
s = super()
print(s.__thisclass__)
print(s.__self_class__)
s.__init__()
class SubClass(Base):
pass
sub = SubClass()
http://www.blog.pythonlibrary.org/2016/05/25/python-201-super/
И про MRO
цитата
Everything started with a post by Samuele Pedroni to the Python development
mailing list. In his post, Samuele showed that the Python 2.2 method resolution order
is not monotonic and he proposed to replace it with the C3 method resolution order.
Guido agreed with his arguments and therefore now Python 2.3 uses C3.
The C3 method itself has nothing to do with Python, since it was invented by people
working on Dylan ...
The list of the ancestors of a class C, including the class itself, ordered from the nearest ancestor to the furthest, is called the class precedence list or the linearization of C.
...
The Method Resolution Order (MRO) is the set of rules that construct the linearization. In the Python literature, the idiom "the MRO of C" is also used as a synonymous for the linearization of the class C.
...
A MRO is monotonic when the following is true: if C1 precedes C2 in the linearization of C, then C1 precedes C2 in the linearization of any subclass of C. Otherwise, the innocuous operation of deriving a new class could change the resolution order of methods, potentially introducing very subtle bugs.
...
C3 MRO
the linearization of C is the sum of C plus the merge of the linearizations of the parents and the list of the parents.
L[C(B1 ... BN)] = C + merge(L[B1] ... L[BN], B1 ... BN)
...
take the head of the first list, i.e L[B1][0]; if this head is not in the tail of any of the other lists, then add it to the linearization of C and remove it from the lists in the merge, otherwise look at the head of the next list and take it, if it is a good head. Then repeat the operation until all the class are removed or it is impossible to find good heads. In this case, it is impossible to construct the merge, Python 2.3 will refuse to create the class C and will raise an exception.
...
Guido points out in his essay that the classic MRO is not so bad in practice, since one can typically avoids diamonds for classic classes. But all new style classes inherit from object, therefore diamonds are unavoidable and inconsistencies shows up in every multiple inheritance graph.
https://www.python.org/download/releases/2.3/mro/
original post http://vasnake.blogspot.com/2016/06/super-mro.html