他の回答はself
、最初のパラメーターに追加することを提案しました。
しかし、通常__init__
、親クラスの の呼び出しは によって行われsuper
ます。
次の例を検討してください。
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
クラスには、コンストラクターと初期化子を呼び出す順序が含まれています。
>>> AB.__mro__
(<class '__main__.AB'>, <class '__main__.B'>, <class '__main__.A'>, <type 'object'>)
最初にAB
が__init__
呼び出され、次に が呼び出され、次に が呼び出され、次に が呼び出さB
れA
ますobject
。
確認しよう:
>>> ab = AB(1)
__init__ is called in AB
__init__ is called in B
__init__ is called in A
しかし、このチェーンを介したこれらの呼び出しは によって行われsuper
ます。と入力するsuper(AB, self)
と、次の意味にAB
なり__mro__
ますself
。
super
次に、 inを呼び出して、チェーン内の:B
の後の次のクラスを探します。B
super(B, self)
後で問題が発生する可能性があるため、super
手動で呼び出すなどしないで使用することが重要です。詳細については、これをお読みください。A.__init__(self,...)
したがって、そのままにしsuper
ておくと、問題が発生します。__init__
あなたのクラスのメソッドは異なるパラメータを期待しています。super
また、これらのクラスのメソッドを呼び出す順序を確実に知ることはできません。順序は、クラス作成時にC3 アルゴリズムによって決定されます。サブクラスでは、別のクラスが呼び出しチェーンの中間に入る場合があります。この場合、メソッドがどのように呼び出される__init__
かを理解するために、常にすべての継承チェーンを考慮する必要があるためです。__init__
たとえば、それらのクラスとC(A)
サブクラスを追加することを検討してください。Thenは afterではなく afterで呼び出されます。D(B)
CD
A
B
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
delegation
なのでここは継承ではなく利用を考えたほうがいいと思います。
class AB(object):
def __init__(self, x, y, z=0):
self.a = A(x,y)
self.b = B(z)
したがって、オブジェクト内a
にb
インスタンスA
とB
クラスを作成するだけです。AB
そして、 と を参照してメソッドを介して必要に応じて使用できself.a
ますself.b
。
委任を使用するかどうかは、質問からは明らかでないケースによって異なります。しかし、それは考慮すべきオプションかもしれません。