class A:
def __init__(self):
print("world")
class B(A):
def __init__(self):
print("hello")
B() # output: hello
私がスーパーコンストラクターで使用した他のすべての言語では、暗黙的に呼び出されます。Pythonでどのように呼び出すのですか?私は期待しsuper(self)
ますが、これは機能しません。
class A:
def __init__(self):
print("world")
class B(A):
def __init__(self):
print("hello")
B() # output: hello
私がスーパーコンストラクターで使用した他のすべての言語では、暗黙的に呼び出されます。Pythonでどのように呼び出すのですか?私は期待しsuper(self)
ますが、これは機能しません。
他の回答と同様に、スーパークラスメソッド(コンストラクターを含む)を呼び出す方法は複数ありますが、Python-3.xではプロセスが簡略化されています。
Python-3.x
class A(object):
def __init__(self):
print("world")
class B(A):
def __init__(self):
print("hello")
super().__init__()
Python-2.x
python 2.xでは、もう少し冗長なバージョンを呼び出す必要があります。これは、ドキュメントsuper(<containing classname>, self)
と同等です。super()
class A(object):
def __init__(self):
print "world"
class B(A):
def __init__(self):
print "hello"
super(B, self).__init__()
super()
新しいスタイルのクラスで親のようなオブジェクトを返します:
class A(object):
def __init__(self):
print("world")
class B(A):
def __init__(self):
print("hello")
super(B, self).__init__()
B()
Python 2.xの古いスタイルのクラスでは、次のようになります。
class A:
def __init__(self):
print "world"
class B(A):
def __init__(self):
print "hello"
A.__init__(self)
1つの方法は、次のように、Aのコンストラクターを呼び出しself
、引数として渡すことです。
class B(A):
def __init__(self):
A.__init__(self)
print "hello"
このスタイルの利点は、それが非常に明確であるということです。Aのイニシャライザーを呼び出します。欠点は、共有基本クラスの初期化子を2回呼び出す可能性があるため、ひし形の継承をうまく処理できないことです。
別の方法は、他の人が示しているように、super()を使用することです。単一継承の場合、基本的には親のイニシャライザーを呼び出せるのと同じことを行います。
ただし、super()は内部的にはかなり複雑であり、多重継承の状況では直感に反する場合があります。プラス面として、super()を使用してひし形の継承を処理できます。super()の機能の要点を知りたい場合は、super()がどのように機能するかについて私が見つけた最良の説明がここにあります(ただし、必ずしもその記事の意見を支持しているわけではありません)。
短い答え
super(DerivedClass, self).__init__()
長い答え
何をしsuper()
ますか?
指定されたクラス名を受け取り、その基本クラスを見つけ(Pythonは多重継承を許可します__init__
)、左から右にそれぞれのメソッド(この場合)を探します。使用可能なメソッドが見つかるとすぐに、それを呼び出して検索を終了します。
すべての基本クラスのinitを呼び出すにはどうすればよいですか?
上記は、基本クラスが1つしかない場合に機能します。ただし、Pythonでは多重継承が許可されているため、すべての基本クラスが正しく初期化されていることを確認することをお勧めします。これを行うには、各基本クラスでinitを呼び出す必要があります。
class Base1:
def __init__():
super(Base1, self).__init__()
class Base2:
def __init__():
super(Base2, self).__init__()
class Derived(Base1, Base2):
def __init__():
super(Derived, self).__init__()
スーパーのinitを呼び出すのを忘れた場合はどうなりますか?
コンストラクター(__new__
)はチェーンで呼び出されます(C ++やJavaのように)。インスタンスが作成されると、そのインスタンスのイニシャライザー(__init__
)のみが呼び出され、スーパークラスへの暗黙のチェーンはありません。
パラメータを使用して例を追加するだけです。
class B(A):
def __init__(self, x, y, z):
A.__init__(self, x, y)
変数x、y、zを定義する必要がある派生クラスBと、x、yを定義する必要があるスーパークラスAが与えられた場合、現在のサブクラスインスタンスへの参照を使用してスーパークラスAの静的メソッドinitを呼び出すことができます。 (自己)そして期待される引数のリスト。
以前の回答を拡張する次の式を使用します。
class A(object):
def __init__(self):
print "world"
class B(A):
def __init__(self):
print "hello"
super(self.__class__, self).__init__()
B()
このようにして、 superの呼び出しでクラスの名前を繰り返す必要はありません。多数のクラスをコーディングしていて、初期化メソッドのコードをクラス名に依存しないようにしたい場合に便利です。