Python2.2以前では、サブクラスが親クラスのメソッドを呼び出す必要がある場合、クラス名を使用して直接クラスのメソッドを呼び出し、つまり非バインドクラスメソッドを呼び出し、自身のオブジェクトselfを渡していました。パラメータとして。
class A(object): def say(self): print 'I am A' class B(A): def say(self): print 'I am B' A.say(self) b = B() b.say()
Output
I am B I am A
これはうまく機能しますが、親クラスの名前を変更すると、親クラスへの明示的な呼び出しを 1 つずつ修正する必要があります。子クラス 親クラスとの結合度が比較的高いクラスです。
そのため、ハードコーディングを回避し、親クラスの名前を気にする必要がないように、Python 2.2 の後に super() 関数が導入されました。
super() 関数を使用すると、上記のコードは次のように記述できます。
class B(A): def say(self): print 'I am B' super(B,self).say()
python3.0 以降、super() 関数はパラメーターを渡す必要がありません。つまり、上記のコード行を直接 super().say() にすることができます。
注意事項:
super は、新しいスタイルのクラスでのみ使用できます。
Super には多重継承の問題があります。サブクラスが複数の親クラスを継承する場合、super は最初の親クラスのメソッドを呼び出します。
親クラスメソッドを呼び出すこれら 2 つの方法を混合しないでください。アンバインド クラス メソッドを使用するか、両方ともスーパーを使用してください。そうしないと、呼び出されないか、複数回呼び出される可能性があります。
しかし:
スーパーについて考えるときに親クラスを考えないでください! super は MRO の次のクラスを指します。
スーパーというと親クラスを思い出しますが、これは初心者が犯しやすい間違いであり、当時の私も犯した間違いでした。
def super(cls, inst): mro = inst.__class__.mro() return mro[mro.index(cls) + 1]
2 つのパラメーター cls と inst はそれぞれ次の 2 つのことを行います:
1. inst は、cls を通じて現在の MRO 内のインデックスを検索し、mro[index + 1] を返します。 】
この2つはスーパーの本質です、必ず覚えておいてください!
MRO は Method Resolution Order の略で、クラスの継承順序を表します。
class Root(object): def __init__(self): print("this is Root") class B(Root): def __init__(self): print("enter B") # print(self) # this will printsuper(B, self).__init__() print("leave B") class C(Root): def __init__(self): print("enter C") super(C, self).__init__() print("leave C") class D(B, C): pass d = D() print(d.__class__.__mro__)
enter B enter C this is Root leave C leave B (,,,,)
super(B, self).__init__()
(
実際、これらすべてのロジックはまだ非常に明確です。重要なのは、super が何を行うかを理解することです。