Pythonでは、どのParentのメソッドを呼び出すかをどのように選択しますか?親ASDF2の__init__
メソッドを呼び出したいとします。 super()でASDF1を指定する必要があるようです。そして、ASDF3の__init__
を呼び出したい場合、ASDF2 ?!を指定する必要があります。
>>> class ASDF(ASDF1, ASDF2, ASDF3):
def __init__(self):
super(ASDF1, self).__init__()
>>> ASDF()
ASDF2's __init__ happened
>>> class ASDF(ASDF1, ASDF2, ASDF3):
def __init__(self):
super(ASDF2, self).__init__()
>>> ASDF()
ASDF3's __init__ happened
私にはおかしなようです。私は何を間違えていますか?
それは super()
の目的ではありません。 Superは基本的に、特定の順序で親の1つ(またはすべて)を選択します。単一の親のメソッドのみを呼び出したい場合は、これを行います
class ASDF(ASDF1, ASDF2, ASDF3):
def __init__(self):
ASDF2.__init__(self)
super
は、メソッド解決順序で次のメソッドを呼び出します。線形継承ツリーでは、直接の親クラスのメソッドになります。
ここには3つの親があり、__init__
の観点からの次のASDF1
メソッドはASDF2
のメソッドです。一般的に、安全なことは、他の何かをしたい理由がわからない限り、継承リストの最初のクラスをsuper
に渡すことです。
このすべてのポイントは、どの__init__
メソッドを呼び出すかを明示的に選択する必要がないようにすることです。ここでの質問は、すべてのスーパークラス__init__
メソッドを呼び出したくない理由です。
Pythonでのsuper
の使用に関するかなり多くの文献があります。トピックをGoogleで検索し、どのような結果になるか読むことをお勧めします。
ASDF1(親クラスの1つ)をsuper()の最初の引数として渡します。それをしないでください。代わりに、super()の最初の引数としてASDFを渡す必要があります。
Python 2.7ドキュメントを引用すると、典型的なスーパークラスの呼び出しは次のようになります。
class C(B):
def method(self, arg):
super(C, self).method(arg)
ここでsuperの最初の引数はCであり、これが現在のクラスであることに注意してください。 B(親クラス)をsuper()に渡さないでください。
メソッド解決順序(MRO)を決定すると、最初の引数として渡されたクラスをスーパースキップし、そのクラスの親と兄弟の検索を開始します。そのため、super()の最初の引数としてASDF1を渡すと、ASDF1をスキップし、ASDF2で検索を開始しました。 ASDF2の__init__
と呼ばれていました。
Python 3では、現在のクラスを渡す必要はありません。
class C(B):
def method(self, arg):
super().method(arg) # This does the same thing as:
# super(C, self).method(arg)
# (Python 3 only)