他の回答は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の後の次のクラスを探します。Bsuper(B, self)
後で問題が発生する可能性があるため、super手動で呼び出すなどしないで使用することが重要です。詳細については、これをお読みください。A.__init__(self,...)
したがって、そのままにしsuperておくと、問題が発生します。__init__あなたのクラスのメソッドは異なるパラメータを期待しています。superまた、これらのクラスのメソッドを呼び出す順序を確実に知ることはできません。順序は、クラス作成時にC3 アルゴリズムによって決定されます。サブクラスでは、別のクラスが呼び出しチェーンの中間に入る場合があります。この場合、メソッドがどのように呼び出される__init__かを理解するために、常にすべての継承チェーンを考慮する必要があるためです。__init__
たとえば、それらのクラスとC(A)サブクラスを追加することを検討してください。Thenは afterではなく afterで呼び出されます。D(B)CDABC
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。
委任を使用するかどうかは、質問からは明らかでないケースによって異なります。しかし、それは考慮すべきオプションかもしれません。