Python 3 の super() と複数継承
Python 3 における super()
関数は、複数継承が絡む場合、特にその挙動が重要です。複数のクラスから継承する場合、super()
はメソッド解決順序(MRO)を利用して、どの親クラスのメソッドを呼び出すかを決定します。このMROは、クラスが定義される際に自動的に計算され、クラスの __mro__
属性に保存されます。
サンプルコード1: 基本的な複数継承
class Base1: def msg(self): return "Base1" class Base2: def msg(self): return "Base2" class Derived(Base1, Base2): def msg(self): return super().msg() # インスタンス化とメソッド呼び出し d = Derived() print(d.msg()) # 出力: Base1
この例では、Derived
クラスが Base1
と Base2
を継承しており、super().msg()
は Base1
の msg()
メソッドを呼び出します。これは、PythonのMROが左から右へと親クラスを解決するためです。
サンプルコード2: MROの確認
class Base1: def msg(self): return "Base1" class Base2: def msg(self): return "Base2" class Derived(Base1, Base2): pass # MROの表示 print(Derived.__mro__) # 出力: (, , , )
このコードは Derived
クラスのメソッド解決順序を表示します。この順番に従って super()
はメソッドを呼び出します。
サンプルコード3: super() を使った複雑な複数継承
class Base1: def msg(self): return "Base1" class Base2(Base1): def msg(self): return super().msg() + " -> Base2" class Base3: def msg(self): return "Base3" class Derived(Base2, Base3): def msg(self): return super().msg() + " -> Derived" # インスタンス化とメソッド呼び出し d = Derived() print(d.msg()) # 出力: Base1 -> Base2 -> Derived
この例では、Derived
クラスが Base2
と Base3
を継承していますが、Base2
はさらに Base1
を継承しています。この場合、super()
は Derived
から Base2
、次に Base1
と継承チェーンをたどります。
これらのサンプルを通じて、Pythonの super()
関数と複数継承の動作原理を理解することができます。MROによってどのメソッドが呼び出されるかが決定されるため、複数継承を使用する際はこの挙動をしっかりと把握しておくことが重要です。