Powiedzmy, że mam scenariusz wielokrotnego dziedziczenia:
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?
Są dwa typowe podejścia do pisania C
„s __init__
:
- (w starym stylu)
ParentClass.__init__(self)
- (nowszy styl)
super(DerivedClass, self).__init__()
Jednak w obu przypadkach, jeśli klasy nadrzędne ( A
i B
) nie są zgodne z tą samą konwencją, kod nie będzie działał poprawnie (niektóre mogą zostać pominięte lub wywoływane wielokrotnie).
Więc jaki jest właściwy sposób? Łatwo jest powiedzieć „po prostu być spójne, wykonaj jedną lub drugą stronę”, ale jeśli A
albo B
są z 3rd biblioteki partii, co wtedy? Czy istnieje podejście, które zapewni wywołanie wszystkich konstruktorów klas nadrzędnych (i we właściwej kolejności i tylko raz)?
Edycja: aby zobaczyć, co mam na myśli, jeśli to zrobię:
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")
Wtedy otrzymuję:
Entering C
Entering A
Entering B
Leaving B
Leaving A
Entering B
Leaving B
Leaving C
Zauważ, że B
init jest wywoływany dwukrotnie. Jeśli zrobię:
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")
Wtedy otrzymuję:
Entering C
Entering A
Leaving A
Leaving C
Zauważ, że B
init nigdy nie jest wywoływany. Wygląda więc na to, że dopóki nie znam / nie kontroluję init klas, z których dziedziczę ( A
i B
) nie mogę dokonać bezpiecznego wyboru dla klasy, którą piszę ( C
).