公式ドキュメントでは、super の定義については詳しく説明されていません。これは、大まかに言うと、いくつかの継承されたメソッドを呼び出すことができるようにするための、最も一般的に使用される状況です。次の例:
サブクラス C は、親クラス B の同名のメソッドを書き換えます。上書き実装では、スーパーによってインスタンス化されたプロキシ オブジェクトを通じて、親クラスの同名のメソッドが呼び出されます。
スーパークラスの初期メソッドシグネチャは次のとおりです:
self を除く 1 つまたは 2 つのパラメータを受け入れます。注釈で述べたように、2 つのパラメータを受け入れる場合、バインドされたスーパー インスタンスが返されます。2 番目のパラメータが省略された場合は、バインドされていないスーパー オブジェクトが返されます。
通常の状況では、継承されたクラスメソッドまたは静的メソッドを呼び出す場合、現時点では super(type, type2).some_method を使用することで目的を達成できます。 obj) がこの場合に使用されます。スーパー オブジェクトには、カスタム実装された getattribute メソッドも使用できます。ただし、後者は通常、インスタンス メソッドの呼び出しに使用されるため、メソッドを検索するときに、対応するインスタンスを渡してバインドされたインスタンス メソッドを取得できます。
リーリーSuper は多くの場所で使用され、指定された型をハードコーディングすることなくプログラムをより動的にするだけでなく、カスタム型を生成するためにベースクラスで new を見つけるためにメタクラスで super を使用するなど、他の特定の場所でも使用する必要があります。テンプレート; カスタム内 属性を取得する際の無限ループなどを防ぐために使用されます。
スーパーについては、Python 記述子と一緒に理解することをお勧めします。スーパーは記述子プロトコルを実装し、非データ記述子であるためです。これは、誰もがスーパーの使用法と動作原理をよりよく理解するのに役立ちます。
同時に、次の 4 つの点に注意してください:
1. 単一継承では、super() と __init__() によって実装される関数は似ています
リーリー
super() 継承を使用する場合、基本クラスを明示的に参照する必要はありません。
2. super() は新しいスタイルのクラスでのみ使用できます
基底クラスを古いスタイルのクラスに変更します。つまり、基底クラスを継承しませんリーリー
リーリー
3. Super は親クラスではなく、継承シーケンスの次のクラスです
多重継承の場合、次の関数と同様に、super() は継承順序で親クラスではなく次のクラスを返すことと同等です。リーリー
例:
リーリー
リーリー
実行プロセスは以下と同等です: childC() を初期化するとき、最初に super(childA, self) を呼び出します。childA のコンストラクターで __init__() は、継承順序で childA の後のものを返します。現在のクラス childB; 次に childB().__init()__ を実行し、この順序で続行します。
多重継承において、childA() の super(childA, self).__init__() を Base.__init__(self) に置き換えると、実行時、childA を継承した後、省略された Base クラスに直接ジャンプします。子供B:
リーリー
super() メソッドから、super() の最初のパラメーターは継承チェーン内の任意のクラスの名前にできることがわかります。
それ自体の場合、順番に次のクラスを継承します継承チェーン内の前のクラスの場合、無限に再帰されます
継承チェーンの後のクラスの場合、継承チェーンの概要自体と受信クラスの間のクラスは無視されます。
たとえば、childA() の super を super(childC, self).__init__() に変更すると、プログラムは無限に再帰的に実行されます。
次のような:
リーリー
4. super() の繰り返し呼び出しを回避できますchildA が Base に基づいている場合、childB は childA と Base を継承し、childB が Base の __init__() メソッドを呼び出す必要がある場合、 __init__() が 2 回実行されます。 リーリー
リーリー