Andere Antworten vorgeschlagen, self
zum ersten Parameter hinzuzufügen.
Aber normalerweise Aufrufe von __init__
in Elternklassen werden von super
gemacht.
Betrachten Sie dieses Beispiel:
class A(object):
def __init__(self, x):
print('__init__ is called in A')
self.x = x
class B(object):
def __init__(self, *args, **kwargs):
print('__init__ is called in B')
super(B, self).__init__(*args, **kwargs)
class AB(B, A):
def __init__(self, *args, **kwargs):
print('__init__ is called in AB')
super(AB, self).__init__(*args, **kwargs)
AB
Klasse enthält eine Reihenfolge, in der Konstrukteurs und initializators sollte aufgerufen werden:
>>> AB.__mro__
(<class '__main__.AB'>, <class '__main__.B'>, <class '__main__.A'>, <type 'object'>)
See, dass erste AB
's __init__
aufgerufen wird, dann B
' s, dann A
's, und dann object
' s.
Lassen Sie uns:
>>> ab = AB(1)
__init__ is called in AB
__init__ is called in B
__init__ is called in A
Aber diese Anrufe durch diese Kette durch super
gemacht. Wenn wir super(AB, self)
eingeben, bedeutet das: Finde dann nächste Klasse nach AB
in __mro__
Kette von self
.
Dann sollten wir super
in B
, rufen Sie für die nächste Klasse in der Kette nach B
suchen: super(B, self)
.
Es ist wichtig, super
zu verwenden und nicht manuell A.__init__(self,...)
usw. aufzurufen, da dies später zu Problemen führen kann. Read this for more info.
Also, wenn Sie mit super
bleiben, dann gibt es ein Problem. __init__
Methoden in Ihren Klassen erwarten unterschiedliche Parameter. Und Sie können nicht sicher die Reihenfolge wissen, in der super
Methoden in diesen Klassen aufrufen wird. Die Reihenfolge wird zum Zeitpunkt der Klassenerstellung durch C3 algorithm festgelegt. In Unterklassen können andere Klassen zwischen die Aufrufkette gelangen. Sie können also keine anderen Parameter in __init__
haben, da Sie in diesem Fall immer alle Vererbungsketten berücksichtigen müssen, um zu verstehen, wie __init__
Methoden aufgerufen werden.
Zum Beispiel in Betracht ziehen, C(A)
und D(B)
Klassen und CD
Unterklasse von ihnen hinzuzufügen. Dann wird A
nicht mehr nach B
aufgerufen, sondern nach C
.
class A(object):
def __init__(self, *args, **kwargs):
print('__init__ is called in A')
super(A, self).__init__(*args, **kwargs)
class B(object):
def __init__(self, *args, **kwargs):
print('__init__ is called in B')
super(B, self).__init__(*args, **kwargs)
class AB(B,A):
def __init__(self, *args, **kwargs):
print('__init__ is called in AB')
super(AB, self).__init__(*args, **kwargs)
class C(A):
def __init__(self, *args, **kwargs):
print('__init__ is called in C')
super(C, self).__init__(*args, **kwargs)
class D(B):
def __init__(self, *args, **kwargs):
print('__init__ is called in D')
super(D, self).__init__(*args, **kwargs)
class CD(D,C):
def __init__(self, *args, **kwargs):
print('__init__ is called in CD')
super(CD, self).__init__(*args, **kwargs)
class ABCD(CD,AB):
def __init__(self, *args, **kwargs):
print('__init__ is called in ABCD')
super(ABCD, self).__init__(*args, **kwargs)
>>> abcd = ABCD()
__init__ is called in ABCD
__init__ is called in CD
__init__ is called in D
__init__ is called in AB
__init__ is called in B
__init__ is called in C
__init__ is called in A
Also ich denke, es ist eine gute Idee, hier zu denken, über die Verwendung von delegation
statt Vererbung.
class AB(object):
def __init__(self, x, y, z=0):
self.a = A(x,y)
self.b = B(z)
So erstellen Sie nur a
und b
Instanzen von A
und B
Klassen innerhalb AB
Objekt. Und dann können Sie sie verwenden, wie Sie durch Methoden unter Bezugnahme auf self.a
und self.b
benötigen.
Die Verwendung oder nicht Delegierung hängt von Ihrem Fall ab, der aus Ihrer Frage nicht klar ist. Aber es könnte eine Option sein, die es zu berücksichtigen gilt.
Warum verwenden Sie hier Vererbung anstelle von Delegation? Da der Fall der Mehrfachvererbung mit 'super' behandelt werden sollte, wird das wegen anderer Parameter in' ___init__' nicht gut funktionieren. – ovgolovin
@ovgolovin Weil ich ein unerfahrener Programmierer bin. Ich weiß nicht, was Delegation ist. Ich werde versuchen, es zu untersuchen. –
@ovgolovin Danke. Es stellte sich heraus, dass ich mein Problem mit einem Wrapper gelöst hatte. –