ホームページ  >  記事  >  バックエンド開発  >  Pythonクラスのsuper()と__init__()の違いについての説明

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

高洛峰
高洛峰オリジナル
2017-03-16 16:08:291372ブラウズ

単一の継承では、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() に変更された場合、プログラムは無限に再帰されます。 例:

  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 &#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 サイトの他の関連記事を参照してください。

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