super()とは
今回はpyhtonのクラスで利用されるsuper()について説明していきます。
super()とは
super()は、一言で言うと
- 親クラスの関数を実行してくれるオプション
です。
使用例から見ていきましょう。
使用例
# 親クラスの設定
class Animal:
def __init__(self, name):
self.name = name
print(f"動物の名前が次のように初期設定されました: {self.name}")
def make_sound(self):
print("動物の鳴き声")
# 子クラス
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name) # 親クラスの__init__メソッドを呼び出す
self.breed = breed
print(f"次の犬種に初期設定されました: {self.breed}")
def make_sound(self): # 親クラス関数の上書き
super().make_sound() # 親クラスのmake_soundメソッドを呼び出す
print("ワンワン")
# オブジェクトを作成してメソッドを呼び出す
d = Dog("レオ", "ゴールデンレトリバー") # ①
d.make_sound() # ②
出力
動物の名前が次のように初期設定されました: レオ # ①で出力
次の犬種に初期設定されました: ゴールデンレトリバー # ①で出力
動物の鳴き声 # ②で出力
ワンワン # ②で出力
上記のように、子クラスから親クラスの関数を呼び出すことができます。
Animalクラスを継承した、Dog(Animal)クラスでは、super()により親クラスの関数を呼び出すことが可能です。
また、super().make_sound()としないと、子クラスの関数が親クラスの関数を上書きしてしまい、子クラスの関数のみが呼び出されるようになってしまいます。次に例を示します。
- 子クラスのmake_soundのみ実行される
# 子クラス
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name) # 親クラスの__init__メソッドを呼び出す
self.breed = breed
print(f"次の犬種に初期設定されました: {self.breed}")
def make_sound(self):
#コメントアウト super().make_sound() # 親クラスのmake_soundメソッドを呼び出す
print("ワンワン")
# オブジェクトを作成してメソッドを呼び出す
d = Dog("レオ", "ゴールデンレトリバー")
d.make_sound()
動物の名前が次のように初期設定されました: レオ
次の犬種に初期設定されました: ゴールデンレトリバー
ワンワン
"動物の鳴き声"が出力されていないことがわかると思います。子クラスのmake_soundが親クラスのmake_soundを上書きしてしまったのです。
※ちなみに、子クラスにmake_sound()を実装せずに実行すると、親関数のコードのみが実行されます。次に示します。
- 親関数のmake_soundのみが実行される
# def make_sound(self):
# super().make_sound() # 親クラスのmake_soundメソッドを呼び出す
# print("ワンワン")
# オブジェクトを作成してメソッドを呼び出す
d = Dog("レオ", "ゴールデンレトリバー")
d.make_sound()
動物の名前が次のように初期設定されました: レオ
次の犬種に初期設定されました: ゴールデンレトリバー
動物の鳴き声
"ワンワン"が出力されていませんね。
以上がsuper()の主な使い方になります。
嬉しいこと
super()の嬉しいことは、次のようになります
- コード量が減る
- 管理しやすく、使いまわせる
これはクラス自体の長所と被ってしまいますが、説明していきます。
例えば、猫用のクラスCatを実装してみましょう。
# 親クラス
class Animal:
def __init__(self, name):
self.name = name
print(f"動物の名前が次のように初期設定されました: {self.name}")
def make_sound(self):
print("動物の鳴き声")
# 子クラス
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name) # 親クラスの__init__メソッドを呼び出す
self.breed = breed
print(f"次の犬種に初期設定されました: {self.breed}")
def make_sound(self):
super().make_sound() # 親クラスのmake_soundメソッドを呼び出す
print("ワンワン")
# オブジェクトを作成してメソッドを呼び出す
d = Dog("レオ", "ゴールデンレトリバー")
d.make_sound()
# 追加 ##############################################################
class Cat(Animal): # 変更
def __init__(self, name, breed):
super().__init__(name) # 親クラスの__init__メソッドを呼び出す
self.breed = breed
print(f"次の猫種に初期設定されました: {self.breed}") # 変更
def make_sound(self):
super().make_sound() # 親クラスのmake_soundメソッドを呼び出す
print("ニャーニャー") # 変更
c = Cat("メイ","ペルシャ猫") # 追加
c.make_sound() # 追加
出力
動物の名前が次のように初期設定されました: レオ
次の犬種に初期設定されました: ゴールデンレトリバー
動物の鳴き声
ワンワン
動物の名前が次のように初期設定されました: メイ
次の猫種に初期設定されました: ペルシャ猫
動物の鳴き声
ニャーニャー
いかがでしょうか。Dogクラスから数行変更するだけでCatクラスが追加できました。super()を使うことで、親クラスと同じコードを書く必要がなくなります。
同じような処理を持つ関数をまとめて管理する際にクラスは便利であり、その中で親クラスの呼び出しを担当するオプションがsuper()です。
super()を使用することで、管理しやすいコードを作ることができるでしょう。
self.メソッド名との違い
親クラスのメソッドを呼び出す方法として
- super().メソッド名()
- self.メソッド名()
の2種類があります。
これらは呼び出し方によって動作が異なります。
super.メソッド名()
1つ上の継承元のメソッドを明示的に呼び出します。
特に、親クラスも他のクラスを継承しているなどの多重継承の際に有用です。
self.メソッド名()
一番最後にオーバーライドされた関数を呼び出します。
注意点として、以下のようにself.__init__()で親クラスの初期化メソッドを呼び出そうとすると、子クラスで既に__init__クラスをオーバーライドしているため、これが再度呼び出され、無限に子クラスの__init__関数が呼び出されます。
# 再帰呼び出し
class Dog(Animal):
def __init__(self, name, breed): # これが再度呼ばれる
self.__init__(name) # これを実行すると
ですので、init関数(コンストラクタ)の呼び出しはsuper()を使うようにしましょう。
まとめ
super()は、継承先の小クラスで親クラスの関数を呼び出す際に使用します。
また、親クラスの関数と同名の関数を子クラスで使用し、関数を上書きする時にも使用されます。
基本的には
- 親クラスの関数を実行してくれるオプション
と覚えておくと良いでしょう。
それでは、最後まで読んでいただきありがとうございました。
補遺
コードを見る中で、親クラスが継承されていないにも関わらずsuper()が使用されているかもしれません。それは、pythonの最も基本的な組み込みクラスのobjectクラスを呼び出しています。
objectクラスには、__str__などの基本的なメソッドが定義されおり、上書きしない限りデフォルトの機能として動作します。
ソフトウェア開発の際には見かけることもあるかもしれません。それとなく理解しておきましょう。
Discussion