Скажіть, у мене є декілька сценаріїв успадкування:
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
є з 3 - сторонньої бібліотеки, що тоді? Чи існує підхід, який може забезпечити виклик усіх конструкторів батьківського класу (у правильному порядку та лише один раз)?
Редагувати: щоб побачити, що я маю на увазі, якщо це зробити:
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 ніколи не викликається. Тож здається, що якщо я не знаю / не контролюю ініціативи класів, які я успадковую від ( A
і B
), я не можу зробити безпечний вибір для класу, про який пишу ( C
).