Pythonクラスのsuper()と__init__()の違いについての説明

高洛峰
リリース: 2017-03-16 16:08:29
オリジナル
1376 人が閲覧しました

単一の継承では、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()継承を使用する場合、明示的にを行う必要がないことです。参照基本クラス。


super() は新しいスタイルのクラスでのみ使用できます


基本クラスを古いスタイルのクラスに変更します。つまり、基本クラスを継承しません

class Base():
    def init(self):
        print 'Base create'
ログイン後にコピー

実行すると、 b:

super(childB, self).init()
TypeError: must be type, not classobj
ログイン後にコピー


super は親クラスではありませんが、継承シーケンスの次のクラスであるというエラーが報告されます


多重継承では、継承シーケンスは 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 &#39;main.childC&#39;>, <class &#39;main.childA&#39;>, <class &#39;main.childB&#39;>, <class &#39;main.Base&#39;>, <type &#39;object&#39;>)
ログイン後にコピー

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 &#39;main.childC&#39;>, <class &#39;main.childA&#39;>, <class &#39;main.childB&#39;>, <class &#39;main.Base&#39;>, <type &#39;object&#39;>)
ログイン後にコピー

super() メソッドからわかるように、super() の最初のパラメータは継承チェーン内の任意のクラスの名前にすることができます。 be in sequence 次のクラスを継承します

継承チェーン内の前のクラスの場合、無限になります


継承チェーンの後のクラスの場合、継承チェーン概要自体と受信クラスは無視されます。 間のクラス:


たとえば、childA() の super が super(childC, self).init() に変更された場合、プログラムは無限に再帰されます。 例:


super() の繰り返し呼び出しを回避できます


childA が Base に基づいており、childB が childA と Base を継承している場合、childB が Base の init() メソッドを呼び出す必要がある場合、次のような問題が発生します。 init() を 2 回実行する:

class Base(object):
    def init(self):
        print &#39;Base create&#39;
class childA(Base):
    def init(self):
        print &#39;enter A &#39;
        Base.init(self)
        print &#39;leave A&#39;
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
ログイン後にコピー


super() を使用すると、繰り返しの呼び出しを回避できます

class Base(object):
    def init(self):
        print &#39;Base create&#39;
class childA(Base):
    def init(self):
        print &#39;enter A &#39;
        super(childA, self).init()
        print &#39;leave A&#39;
class childB(childA, Base):
    def init(self):
        super(childB, self).init()
b = childB()
print b.class.mro()
enter A 
Base create
leave A
[<class &#39;main.childB&#39;>, <class &#39;main.childA&#39;>, <class &#39;main.Base&#39;>, <type &#39;object&#39;>]
ログイン後にコピー


以上がPythonクラスのsuper()と__init__()の違いについての説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート