単一の継承では、super()とinit()によって実装される関数は似ています
class Base(object): def init(self): print 'Base create' class childA(Base): def init(self): print 'creat A ', Base.init(self) class childB(Base): def init(self): print 'creat B ', super(childB, self).init() base = Base() a = childA() b = childB()
出力結果:
Base create creat A Base create creat B Base create
違いは、super()継承を使用する場合、明示的にを行う必要がないことです。参照基本クラス。
基本クラスを古いスタイルのクラスに変更します。つまり、基本クラスを継承しません
class Base(): def init(self): print 'Base create'
実行すると、 b:
super(childB, self).init() TypeError: must be type, not classobj
多重継承では、継承シーケンスは super() と同等です。親クラスではなく、継承シーケンスの次のクラスを返します。次のような関数:
def super(class_name, self): mro = self.class.mro() return mro[mro.index(class_name) + 1]
mro() は、クラスの継承順序を取得するために使用されます。 例:
class Base(object): def init(self): print 'Base create' class childA(Base): def init(self): print 'enter A ' # Base.init(self) super(childA, self).init() print 'leave A' class childB(Base): def init(self): print 'enter B ' # Base.init(self) super(childB, self).init() print 'leave B' class childC(childA, childB): pass c = childC() print c.class.mro
出力結果は次のとおりです:
enter A enter B Base create leave B leave A (<class 'main.childC'>, <class 'main.childA'>, <class 'main.childB'>, <class 'main.Base'>, <type 'object'>)
supder は親クラスに関連していないため、実行順序は A —> で、最初に childA の
で super(childA, self).init() を呼び出します。コンストラクター、super(childA, self) は、現在のクラスの継承順序で childA の後にクラス childB を返し、その後 childB() .init() を実行します。この順序で実行されます。
多重継承において、childA()のsuper(childA, self).init()をBase._init_(self)に置き換えると、実行時にchildAを継承した後、Baseクラスに直接ジャンプします。そして childB はスキップされます:
enter A Base create leave A (<class 'main.childC'>, <class 'main.childA'>, <class 'main.childB'>, <class 'main.Base'>, <type 'object'>)
super() メソッドからわかるように、super() の最初のパラメータは継承チェーン内の任意のクラスの名前にすることができます。 be in sequence 次のクラスを継承します
継承チェーン内の前のクラスの場合、無限になります
継承チェーンの後のクラスの場合、継承チェーン概要自体と受信クラスは無視されます。 間のクラス:
たとえば、childA() の super が super(childC, self).init() に変更された場合、プログラムは無限に再帰されます。 例: File "test.py", line 12, in init
super(childC, self).init()
File "test.py", line 12, in init
super(childC, self).init()
File "test.py", line 12, in init
super(childC, self).init()
File "test.py", line 12, in init
super(childC, self).init()
File "test.py", line 12, in init
super(childC, self).init()
File "test.py", line 12, in init
super(childC, self).init()
File "test.py", line 12, in init
super(childC, self).init()
File "test.py", line 12, in init
super(childC, self).init()
File "test.py", line 12, in init
super(childC, self).init()
RuntimeError: maximum recursion depth exceeded while calling a Python object
super() の繰り返し呼び出しを回避できます
childA が Base に基づいており、childB が childA と Base を継承している場合、childB が Base の init() メソッドを呼び出す必要がある場合、次のような問題が発生します。 init() を 2 回実行する:
class Base(object): def init(self): print 'Base create' class childA(Base): def init(self): print 'enter A ' Base.init(self) print 'leave A' class childB(childA, Base): def init(self): childA.init(self) Base.init(self) b = childB()
Base の init() メソッドは 2 回実行されます
enter A Base create leave A Base create
class Base(object): def init(self): print 'Base create' class childA(Base): def init(self): print 'enter A ' super(childA, self).init() print 'leave A' class childB(childA, Base): def init(self): super(childB, self).init() b = childB() print b.class.mro() enter A Base create leave A [<class 'main.childB'>, <class 'main.childA'>, <class 'main.Base'>, <type 'object'>]
以上がPythonクラスのsuper()と__init__()の違いについての説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。