Python : super().__init__()は基底クラスのコンストラクタをオーバーライドする

TwitterFacebookHatena
  • 公開:2021-9-3
  • 更新:2023-10-26
  • 文章量:1891
  • Python

TL;DR

基底クラスのコンストラクタをオーバーライドするなら、スーパークラスのコンストラクタも呼び出す必要がある。なぜなら、オブジェクトがきちんと初期化されないからだ。

super().__init__() のポイント

  • 基底クラス(継承元)のコンストラクタをオーバーライドする
  • コンストラクタの上書きはsuper().__init__()
  • メソッドの上書きはsuper().メソッド名()

メソッドを上書きする場合

基底クラスのメソッドやコンストラクタを上書きするには、名前を明示することなく親クラスを参照できる super() を使う。

super([type[, object-or-type]]) - 組み込み関数 — Python 3.9.4 ドキュメント

例えば、基底クラスが持つメソッドと同名のメソッドを定義すると、そのメソッドを上書きできる。基底クラスのメソッドやコンストラクタを利用する場合、明示的に呼び出す必要がある。

# 基底クラス(継承元)
class Parent:
    def __init__(self, a, b):
        self.a = a
        self.b = b
    def w(self):
        return self.b

# 継承先
class Child(Parent):
    def w(self): # メソッドのオーバーライド
        return super().w()

child = Child(0, 'hello')
child.w()

# 'hello'

基底クラスのコンストラクタを上書きする場合

サブクラスにおいて、コンストラクタを定義したい場合はどうすればいいのだろうか?

サブクラスで__init__を定義すると、親の__init__が上書きされてしまう。親の__init__を、サブクラスで上書きすると未定義のままになり、以下のような例外が発生する。

AttributeError    Traceback (most recent call last)

エラーが起こらないように、親クラスのコンストラクタをオーバーライドする場合も、__init__の処理の最初に、スーパークラスの__init__の呼び出しをするとよい。

class クラス名(継承元クラス):
    def __init__(self, 引数):
        super().__init__(引数)
        処理

以下のコードは、基底クラスのコンストラクタをオーバーライドする例である。

# 基底クラス(継承元)
class A:
    def __init__(self, name):
       self.name = name

# 継承先
class B(A):
    def __init__(self, name, mail):
        super().__init__(name) # 基底クラスのコンストラクタをオーバーライド
        self.mail = mail

b = B("yamada", "gmail")
b.name

# 'yamada'

super().__init__()をつけることで、親クラスの__init__と同じ処理を実行してくれるのである。

# 基底クラス(継承元)
class Parent:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def my_name(self):
        print("名前は" + self.name + "。年齢は" + str(self.age) + "歳。")

# 継承先
class Child(Parent):
    def __init__(self, name, age):
        super().__init__(name, age)  # 基底クラスのコンストラクタをオーバーライド

    def my_hello(self):
        print("こんにちは")

# インスタンス化
yamada = Child("山田", 20)
yamada.my_name()
yamada.my_hello()

# 名前は山田。年齢は20歳。
# こんにちは

Python : super().__init__()は基底クラスのコンストラクタをオーバーライドする