Не указано этот случай. Но вообще, и особенно, когда вы используете множественное наследование, super()
делегатов к следующему объекту в Метод Разрешение заказа (MRO) как указано в documentation:
super([type[, object-or-type]])
Возвращает прокси-объект, который делегирует вызов метода родительскому объекту или si bling класс типа. Это полезно для доступа к унаследованным методам , которые были переопределены в классе. Порядок поиска такой же, как и , используемый getattr()
, за исключением того, что сам тип пропускается.
__mro__
атрибут типа перечисляет порядок поиска разрешения метод, используемый как getattr()
и super()
. Атрибут является динамическим и может меняться всякий раз, когда обновляется иерархия наследования .
(...)
(копирование, добавлена полужирный)
Скажем, например, можно определить классы, как (заимствовано из this question, where the MRO is discussed in more detail):
class F:
def __init__(self):
print('F%s'%super().__init__)
super().__init__()
class G:
def __init__(self):
print('G%s'%super().__init__)
super().__init__()
class H:
def __init__(self):
print('H%s'%super().__init__)
super().__init__()
class E(G,H):
def __init__(self):
print('E%s'%super().__init__)
super().__init__()
class D(E,F):
def __init__(self):
print('D%s'%super().__init__)
super().__init__()
class C(E,G):
def __init__(self):
print('C%s'%super().__init__)
super().__init__()
class B(C,H):
def __init__(self):
print('B%s'%super().__init__)
super().__init__()
class A(D,B,E):
def __init__(self):
print('A%s'%super().__init__)
super().__init__()
Тогда __mro__
из A
является:
A.__mro__ == (A,D,B,C,E,G,H,F,object)
Теперь, если мы позвоним A()
, он печатает:
A<bound method D.__init__ of <__main__.A object at 0x7efefd8645c0>>
D<bound method B.__init__ of <__main__.A object at 0x7efefd8645c0>>
B<bound method C.__init__ of <__main__.A object at 0x7efefd8645c0>>
C<bound method E.__init__ of <__main__.A object at 0x7efefd8645c0>>
E<bound method G.__init__ of <__main__.A object at 0x7efefd8645c0>>
G<bound method H.__init__ of <__main__.A object at 0x7efefd8645c0>>
H<bound method F.__init__ of <__main__.A object at 0x7efefd8645c0>>
F<method-wrapper '__init__' of A object at 0x7efefd8645c0>
<__main__.A object at 0x7efefd8645c0>
так это означает, что в контексте A
и при попытке получить __init__
что:
super().__init__
из A
является D.__init__
;
super().__init__
D
является B.__init__
;
super().__init__
of B
является C.__init__
;
super().__init__
из C
- E.__init__
;
super().__init__
E
- G.__init__
;
super().__init__
из G
- H.__init__
;
super().__init__
of H
является F.__init__
; и
super().__init__
от F
является object.__init__
.
Примечание таким образом, что super()
делает по себе не делегатов родителю. Например, super()
от D
составляет B
и B
не является суперклассом D
, поэтому действительно зависит от типа объекта (не от класса).
Теперь в случае D
, то __mro__
является:
D.__mro__ = (D,E,G,H,F,object)
Если мы строим D
однако мы получаем:
D<bound method E.__init__ of <__main__.D object at 0x7efefd864630>>
E<bound method G.__init__ of <__main__.D object at 0x7efefd864630>>
G<bound method H.__init__ of <__main__.D object at 0x7efefd864630>>
H<bound method F.__init__ of <__main__.D object at 0x7efefd864630>>
F<method-wrapper '__init__' of D object at 0x7efefd864630>
Так в контексте D
он считает, что:
super().__init__
от D
- E.__init__
;
super().__init__
E
- G.__init__
;
super().__init__
из G
- H.__init__
;
super().__init__
of H
является F.__init__
; и
super().__init__
от F
является object.__init__
.
Так вот super()
из D
приводит к E
(для __init__
) которая не то же самое в контексте A
.
'super()' разрешает вызов с использованием ** MRO ** ... –
Только разные, если ваш подкласс имеет несколько суперклассов, или если вы в какой-то момент можете изменить свой подкласс для наследования с другой суперкласс. Btw, «родительский класс» не является обычной терминологией для наследования. – khelwood
@khelwood: строго говоря, это неверно: если вы подклассифицируете класс с множественным наследованием, ваш 'super()' может фактически делегировать slibing, а не родительский. Он просто возвращает следующий в строке '__mro__'. –