Скажем, у меня есть сценарий множественного наследования:
class A(object):
# code for A here
class B(object):
# code for B here
class C(A, B):
def __init__(self):
# What's the right code to write here to ensure
# A.__init__ and B.__init__ get called?
Там две типичные подходы к письменной форме C
«s __init__
:
- (Старый стиль)
ParentClass.__init__(self)
- (Новый стиль)
super(DerivedClass, self).__init__()
Однако, в любом случае, если родительские классы ( A
и B
) не следуют одному и тому же соглашению, тогда код не будет работать правильно (некоторые могут быть пропущены или вызваны несколько раз).
Так что опять правильно? Легко сказать «просто будьте последовательны, следуйте одному или другому», но если A
или B
из сторонней библиотеки, что тогда? Есть ли подход, который может обеспечить вызов всех конструкторов родительских классов (и в правильном порядке, и только один раз)?
Изменить: чтобы увидеть, что я имею в виду, если я делаю:
class A(object):
def __init__(self):
print("Entering A")
super(A, self).__init__()
print("Leaving A")
class B(object):
def __init__(self):
print("Entering B")
super(B, self).__init__()
print("Leaving B")
class C(A, B):
def __init__(self):
print("Entering C")
A.__init__(self)
B.__init__(self)
print("Leaving C")
Тогда я получаю:
Entering C
Entering A
Entering B
Leaving B
Leaving A
Entering B
Leaving B
Leaving C
Обратите внимание, что B
init вызывается дважды. Если я сделаю:
class A(object):
def __init__(self):
print("Entering A")
print("Leaving A")
class B(object):
def __init__(self):
print("Entering B")
super(B, self).__init__()
print("Leaving B")
class C(A, B):
def __init__(self):
print("Entering C")
super(C, self).__init__()
print("Leaving C")
Тогда я получаю:
Entering C
Entering A
Leaving A
Leaving C
Обратите внимание, что B
init никогда не вызывается. Таким образом, кажется, что если я не знаю / не контролирую init классов, которые я наследую ( A
и B
), я не могу сделать безопасный выбор для класса, который я пишу ( C
).