54

Pythonで、呼び出す親のメソッドを選択するにはどうすればよいですか?親ASDF2の__init__メソッドを呼び出したいとします。super()..でASDF1を指定する必要があるようです。また、ASDF3を呼び出したい場合は、 ASDF2__init__を指定する必要がありますか?!

>>> 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

私にはばかげているようです。私は何が間違っているのですか?

4

3 に答える 3

80

それsuper()は目的ではありません。Superは基本的に、特定の順序で親の1つ(またはすべて)を選択します。ひとり親のメソッドのみを呼び出したい場合は、これを行います

class ASDF(ASDF1, ASDF2, ASDF3):
    def __init__(self):
        ASDF2.__init__(self)
于 2013-01-07T23:45:16.027 に答える
10

superメソッド解決順序で次のメソッドを呼び出します。線形継承ツリーでは、それは直接の親クラスからのメソッドになります。

ここでは、3つの親があり、の観点__init__からの次の方法はの方法です。一般に、安全な方法は、他のことをしたい理由がわからない限り、継承リストの最初のクラスをに渡すことです。ASDF1ASDF2super

このすべてのポイントは、__init__呼び出すメソッドを明示的に選択する必要がないようにすることです。__init__ここでの問題は、なぜすべてのスーパークラスメソッドを呼び出したくないのかということです。

Pythonでの使用に関するかなりの量の文献がありsuperます。トピックをグーグルで検索し、結果を読むことをお勧めします。

于 2013-01-07T23:46:40.303 に答える
6

super()の最初の引数としてASDF1(親クラスの1つ)を渡します。そうしないでください。代わりに、super()の最初の引数としてASDFを渡す必要があります。

super()のPython2.7ドキュメント

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)
于 2014-09-10T20:53:25.887 に答える