ホームページ >バックエンド開発 >Python チュートリアル >多重継承におけるスーパーコールの詳細

多重継承におけるスーパーコールの詳細

巴扎黑
巴扎黑オリジナル
2016-11-26 09:56:291309ブラウズ

注: ここでは Python 3 が動作環境として使用されており、例は「Python Cookbook」の第 8 章から引用されています。

Python では、サブクラスが親クラスを初期化する場合、主に 2 つの方法があります。1 つ目は親クラス名を直接渡す方法で、2 つ目はスーパー メソッドを使用する方法です。単一継承では両者に違いはありませんが、多重継承では注意が必要な微妙な違いがいくつかあります。例の説明は最後です!
1. 親クラス名を使用する場合:

Pythonコード

class Base:

def __init__(self):

print('Base.__init__')

class A (Base): def __init __(self):sured sured used useを使用して使用して使用します - アウトアウトを介してアウトアウトアウトアウトアウトアウトアウトアウトアウトアウトアウトアウトアウトアウトアウトアウトアウトアウトアウトアウトアウトアウトアウトアウトアウト、

Base.__init__(self) " B.__init__(self)

print( 'C.__init__')

この時点で、クラス C をインスタンス化すると、以下が出力されます:

Python コード

>&gと; > c = C()

Base.__init__

A.__init__

Base .__init__

C.__init__

>>>基地が見えたクラスは 2 回呼び出されます。多くの場合、これは私たちが望む結果ではないはずなので、現時点ではスーパーメソッドの使用を検討できます。

2. superの使用状況:

Pythonコード

class Base:


def __init__(self):

print('Base.__init__')

class A (Base):

def __ init __(self):

super().__ init __()

)super()to super()hereこのとき:

Python コード & & gt; & gt; c = c ()

base .____

B. __init__

>> >

Base クラスが 1 回だけ呼び出されていることがわかります。しかし、残念ながら、これが私がこのブログ記録を書こうと思ったきっかけではありません。なぜなら、注意深く観察すると、Base クラスは予想どおり実際に 1 回しか呼び出されませんが、最初に "B.__init__" が出力され、次に "" が出力されることに気づきましたか? A.__init__"?また、これによって Base が 1 回だけ初期化されるのはなぜでしょうか?あなたも少し混乱しているはずですよね?実際、これはすべて、多重継承中のスーパーの呼び出しプロセスに「責任」があると考えられます。 Python がクラス (継承だけでなく) を実装すると、次の例のように、クラス属性 __mro__ を通じて表示できる解析順序リストを生成するメソッドが生成されます。 ; C.__mro__

(<クラス '__main__.C'>, <クラス '__main__.A'>, <クラス '__main__.B'>,

<クラス '__main__.Base' >、<クラス 'オブジェクト'>)

>>>


そのため、プロパティまたはメソッドを検索するときは、このプロパティまたはメソッドに一致する最初のクラスが見つかるまで、このリストに従って各クラスを反復処理します。継承で super を使用する場合、インタプリタは、スーパーに遭遇しなくなるかリストが走査されるまで、スーパーに遭遇するたびにリスト上の次のクラスを検索し、再帰と同様にレイヤーごとに返します。したがって、この例の検索プロセスは次のようになります。 C で super に遭遇 --> リスト内の次のクラス、つまり A を検索 --> A で再び super に遭遇、B を検索 --> B で super が再出現、 search Base --> Base クラスを初期化し、再帰的に返します。
プロセスをよりわかりやすく説明するために、ここでクラス B のスーパー行をコメント アウトしてください:

Python コード

class B(Base):

def __init__(self):

#super().__init__( )

)super()ここでsuper()initinit __

c.__ init__

baseクラスは出力を生成しなくなりました!なぜ? B にはスーパーがないため、リストでは Base クラスの検索がブロックされ、Base は初期化されません。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
前の記事:Python - 時間変換次の記事:Python - 時間変換