Python superの使い方

この記事のポイント

Pythonのsuperは親クラスのメソッドを呼び出すために欠かせない組み込み関数です。

この記事を読むと、次のようなことが身に付きます。

  • 親クラスのメソッドを安全に呼び出す方法がわかる
  • コードの重複を減らし、保守性を高める書き方を学べる
  • 複数のクラスを継承したときのsuperの便利な使い方を知る

この記事を通して、super()の正しい使い方をマスターすれば、オブジェクト指向のコードをより簡潔で柔軟に書けるようになります。

目次

superとは?

Pythonのsuperとは、クラスの継承において、親クラス(スーパークラス)のメソッドを呼び出すための組み込み関数です。子クラス(サブクラス)から、親クラスが持っている機能(メソッド)を使いたいときに活躍します。

以前は親クラスの名前を直接指定して呼び出す方法もありましたが、superを使うとコードのメンテナンスがしやすくなります。例えば、親クラスの名前が変わった場合でも、superで書かれた部分を修正する必要がありません。

また、複数の親クラスを持つ多重継承の仕組みを使うときに特に役立ちます。superは、Pythonが定めた呼び出し順序(MRO: Method Resolution Order)に従って、適切な親クラスの機能を自動で呼び出してくれます。

superを活用すると、同じコードを何度も書くことを避ける「DRY原則(Don't Repeat Yourself)」を守りやすくなり、コード全体を簡潔に保てます。

superの特徴

  • 親クラス(スーパークラス)のメソッドを呼び出すために使う
  • 親クラス名を直接指定する必要がなくなりコードの保守性が向上する
  • 親クラスの名前が変更されても呼び出し側を修正する必要がない
  • 多重継承の際に適切な順序(MRO)で親クラスのメソッドを自動で呼び出す
  • コードの重複を減らし簡潔さを保つ「DRY原則」の維持に役立つ

【関連】
Pythonをもっと詳しく学ぶならpaizaラーニング

基本構文

Python superの基本的な使い方を見てみましょう。一般的な構文は以下のとおりです。

class 子クラス(親クラス): def メソッド(self, 引数...): super().メソッド(引数...) # 追加の処理

具体的な例として、シンプルな継承関係を表現してみましょう。

class どうぶつ: def 鳴く(self): print("なにか音を出します") class イヌ(どうぶつ): def 鳴く(self): super().鳴く() # 親クラスの鳴く()メソッドを呼び出す print("ワン!ワン!") pochi = イヌ() pochi.鳴く()

出力結果

なにか音を出します
ワン!ワン!

この例では、イヌクラスがどうぶつクラスの鳴く()メソッドをオーバーライド(上書き)しています。イヌクラスの鳴く()メソッド内では、まずsuper().鳴く()によって親クラス(どうぶつ)の鳴く()が呼び出され、「なにか音を出します」が出力されます。その後、イヌクラス独自の処理として「ワン!ワン!」が出力されています。

次に、クラスが作られるとき(インスタンス化)に自動で呼ばれるコンストラクタ(__init__メソッド)で使う例を見てみましょう。

class どうぶつ: def __init__(self, 名前): self.名前 = 名前 print(f"{self.名前}というどうぶつを作成しました") class ネコ(どうぶつ): def __init__(self, 名前, 年齢): super().__init__(名前) # 親クラスの初期化 self.年齢 = 年齢 print(f"{self.名前}は{self.年齢}歳です") tama = ネコ("タマ", 3)

出力結果

タマというどうぶつを作成しました
タマは3歳です

この例では、ネコクラスのコンストラクタ(__init__)でsuperを使い、親クラス(どうぶつ)のコンストラクタを呼び出しています。

親クラスの処理で「タマというどうぶつを作成しました」が出力され、その後、子クラスの処理で「タマは3歳です」が出力されます。親クラスの初期化処理を再利用しつつ、子クラス独自の処理を追加する定番の使い方です。

実用例

super関数の理解を深めるために、さまざまな実用例を見ていきましょう。各例では、実際のコードとその説明を通じて、superがどのように役立つかを示します。

単純な継承でのメソッド拡張

親クラスのメソッドを拡張する最も基本的な使い方です。

class どうぶつ: def 食べる(self): print("食べものを食べています") class ウサギ(どうぶつ): def 食べる(self): print("ニンジンを見つけました") super().食べる() usagi = ウサギ() usagi.食べる()

出力結果

ニンジンを見つけました
食べものを食べています

この例では、ウサギクラスの食べる()メソッドが呼ばれると、まず「ニンジンを見つけました」が出力されます。

次にsuper().食べる()によって親クラス(どうぶつ)の食べる()メソッドが実行され、「食べものを食べています」が出力されます。super()を使い親クラスの機能を再利用することで、コードの重複を避けられます。

コンストラクタの拡張と属性の追加

子クラスで新しい属性を追加する場合の例です。

class どうぶつ: def __init__(self, 名前): self.名前 = 名前 class イヌ(どうぶつ): def __init__(self, 名前, 品種): super().__init__(名前) self.品種 = 品種 pochi = イヌ("ポチ", "柴犬") print(f"{pochi.名前}は{pochi.品種}です")

出力結果

ポチは柴犬です

この例では、イヌクラスのインスタンス作成時にsuper().__init__("ポチ")が呼ばれ、親クラス(どうぶつ)でself.名前が設定されます。

その後、子クラス(イヌ)でself.品種が設定されます。super()を使うことで、名前属性に関する初期化コードを親クラスに任せ、子クラスでは品種属性の追加に集中できています。

多重継承における活用

superが特に力を発揮するのが、複数の親クラスを持つ多重継承の場合です。

class 哺乳類: def 特徴(self): print("体温が一定です") class 肉食動物: def 特徴(self): print("肉を食べます") super().特徴() class ネコ(肉食動物, 哺乳類): def 特徴(self): print("ニャーと鳴きます") super().特徴() neko = ネコ() neko.特徴()

出力結果

ニャーと鳴きます
肉を食べます
体温が一定です

この例では、ネコクラスの特徴()が呼ばれると、まず「ニャーと鳴きます」が出力されます。

次にsuper().特徴()が、MRO(メソッド解決順序)に従い肉食動物クラスの特徴()を呼び出します。そこでもsuper()が呼ばれ、最終的に哺乳類クラスの特徴()が呼ばれます。結果として、継承順序(ネコ→肉食動物→哺乳類)に沿って処理が実行されます。

メソッドのオーバーライドと部分的再利用

親クラスの機能の一部だけを変更(オーバーライド)し、他の機能はそのまま使いたい場合に役立ちます。

class 形: def 面積(self): return 0 def 説明(self): print(f"この形の面積は{self.面積()}です") class 円(形): def __init__(self, 半径): self.半径 = 半径 def 面積(self): return 3.14 * self.半径 * self.半径 circle = 円(5) circle.説明()

出力結果

この形の面積は78.5です

この例では、円クラスのインスタンスで説明()メソッドを呼び出しています。円クラス自身は説明()を定義していませんが、親クラス(形)から継承しています。

親クラスの説明()メソッドは内部でself.面積()を呼び出します。selfは円のインスタンスを指すため、円クラスでオーバーライドされた面積()メソッドが呼ばれ、正しい円の面積が計算されます。

クラスメソッドでのsuperの利用

superは、@classmethodデコレータを付けたクラスメソッド内でも使えます。

class 動物種: @classmethod def 情報(cls): return "生物の一種です" class ペンギン(動物種): @classmethod def 情報(cls): 親情報 = super().情報() return f"{親情報} 泳げる鳥です。" print(ペンギン.情報())

出力結果

生物の一種です 泳げる鳥です。

この例では、ペンギン.情報()というクラスメソッドを呼び出しています。

ペンギンクラスの情報()メソッド内では、super().情報()によって親クラス(動物種)の情報()メソッドが呼ばれ、「生物の一種です」という文字列が取得されます。そして、その文字列に「 泳げる鳥です。」を追加したものが最終的な結果となります。

プライベートメソッドと組み合わせた例

内部的な処理(ここではアンダースコア_で始まるメソッド)とsuper()を組み合わせる例です。

class どうぶつ: def __init__(self): self._エネルギー = 100 def _消費(self, 量): self._エネルギー -= 量 def 行動(self, 活動名): print(f"{活動名}しています") self._消費(10) class トリ(どうぶつ): def 行動(self, 活動名): super().行動(活動名) if 活動名 == "飛ぶ": self._消費(20) # 飛ぶと追加でエネルギー消費 bird = トリ() bird.行動("飛ぶ") print(bird._エネルギー)

出力結果

飛ぶしています
70

この例では、トリクラスの行動("飛ぶ")が呼ばれています。

まずsuper().行動("飛ぶ")が実行され、親クラスの行動()により「飛ぶしています」が出力され、エネルギーが10消費されます。その後、トリクラスのif文の条件に当てはまるため、追加でエネルギーが20消費されます。最終的なエネルギーは100 - 10 - 20 = 70となります。

継承チェーンでの使用

複数世代にわたる継承(例 A→B→C)でも、superは適切に動作します。

class A: def メソッド(self): print("Aのメソッド") class B(A): def メソッド(self): print("Bのメソッド") super().メソッド() class C(B): def メソッド(self): print("Cのメソッド") super().メソッド() c = C() c.メソッド()

出力結果

Cのメソッド
Bのメソッド
Aのメソッド

この例では、Cクラスのインスタンスcのメソッド()を呼び出しています。まずCのメソッド()が実行され「Cのメソッド」が出力されます。

次にsuper()によってBのメソッド()が呼ばれ「Bのメソッド」が出力されます。さらにsuper()によってAのメソッド()が呼ばれ「Aのメソッド」が出力されます。super()が継承チェーンをさかのぼって順番に処理を実行しているのが分かります。

古い形式のsuper呼び出し

Python 2と互換性を持たせるために、引数を指定する形式も知っておくと役立ちます。

class どうぶつ: def 鳴く(self): print("なにか音を出します") class クマ(どうぶつ): def 鳴く(self): # 古い形式(Python 2互換) super(クマ, self).鳴く() print("ガオー!") bear = クマ() bear.鳴く()

出力結果

なにか音を出します
ガオー!

この例では、super(クマ, self).鳴く()という形式で親クラスのメソッドを呼び出しています。

Python 3では引数なしのsuper().鳴く()と書くのが一般的ですが、Python 2ではこのようにクラス名とselfを明示的に指定する必要がありました。現在では主にPython 3の引数なしの形式を使います。

まとめ

Pythonのsuperは、クラスの継承を扱ううえで非常に役立つ組み込み関数です。この記事では、基本的な使い方から多重継承での活用例まで解説しました。

superが活躍する場面

  • 親クラスの機能を呼び出しつつ機能を追加したいとき
  • 子クラスで親クラスの初期化(__init__)を行いたいとき
  • 多重継承で親クラスの機能を順番に呼び出したいとき

superを用いる上で、押さえておきたいポイントを覚えておきましょう。

重要なポイント

  • MRO(メソッド解決順序)というルールに従って動作する
  • 親クラスの名前を直接書かなくて済むため保守性が上がる
  • 引数なしのsuper()を使うのが現在の標準的な書き方

初めてPythonを学ぶ方も、この記事で紹介したsuperを実際に書いて、クラス継承の仕組みを試してみてください。

親クラスの機能をうまく再利用するコードは、実際の開発でよく使用されます。マスターしておけば役立つこと間違いなしです。

ぜひsuperをマスターして、より柔軟で保守性の高いプログラムを作成できるようになりましょう。

レベルを更に上げたい方はpaizaプログラミングスキルチェックへ

  1. paizaラーニングトップ
  2. リファレンス
  3. Pythonのリファレンス記事一覧
  4. Python superの使い方