Pythonのsuper関数の使い方について解説!そもそもPythonのsuperとは?
- システム
エンジニア - Pythonのsuper関数について教えていただけますか。
- プロジェクト
マネージャー - 分かりました。super関数を理解する上で不可欠なクラスと継承、インスタンス、メソッド、アトリビュートなどについてもサンプルプログラムを交えながら解説しましょう。
Pythonのsuperとは?
Pythonのsuperとはスーパークラス(親クラス)に関するオブジェクトを返す関数です。super関数が返すオブジェクトを使うと親クラスの「メソッド」にアクセスすることができます。ちなみにこのオブジェクトを使ってアトリビュートにアクセスすることはできません。
上記の説明で分かってしまった方は、以下を読む必要はありません。良く分からないという方は、クラスと継承の他、インスタンス、メソッド、アトリビュートなど関連するものを一通り理解しないと「良く分からない」と思いますので、その辺の解説をします。
以下に示すプログラムはPython3で動作させてください。動作確認はWindows10とPython3.9.1を使用して行いました。
クラスについて
Pythonはオブジェクト指向のプログラミング言語です。「オブジェクト指向」の「オブジェクト」とは大雑把に言いますと「関連するプログラムとデータをひとまとまりにしたもの」ということになります。
データを操作するにはプログラムが必要ですが、そのデータとプログラムをひとまとめにしてブラックボックスにしてしまえば、後は使い方さえ分かっていれば問題なくそのオブジェクトを使うことができます。
クラスとはオブジェクトの設計図のようなものです。アトリビュート(クラス内の変数)と、メソッド(クラスで定義した関数をメソッドと言います)の定義をします。定義と言ってもPythonの場合はアトリビュートを使うとき(変数に代入しようとしたとき)に自動的に作成されますので、実質的にはメソッドの定義と言っても良いでしょう。
以下に簡単なExampleClassクラスの定義を示します。この関数はメソッドを定義していないので何もしないクラスになります。インスタンスとは、classで定義(設計)した内容を元にメモリ上に実体化したもの(オブジェクト)です。
1
2
3
4
|
class ExampleClass:
pass # 何もしないことを表す特殊な命令です
o = ExampleClass() # 何もしないインスタンス(オブジェクト)を作成
|
クラスの継承
クラスは設計図のようなものなので既存のクラスを継承して機能を拡張したり、改良したりできます。
下記のプログラムの親クラスではaddとpiメソッドを定義しています。子クラスは親クラスを継承していますので、addメソッドとpiメソッドを使用できます。更に子クラスでは、新たにsubメソッドを定義しています。
また、子クラスではpiメソッドを改めて定義(オーバーライド)しています。オーバーライドした場合は、改めて定義した方のメソッドが実行されますので、この場合には円周率のリターン値の精度が上がります。
しかし、オーバーライドする前の(親クラスの)メソッドを呼び出したいということもあります。そんな時に使われるのがsuper関数です。詳細は後述します。
なお、継承元となるクラスは「基底クラス」「親クラス」「スーパークラス」などと呼ばれ、継承先となるクラスは「派生クラス」「子クラス」「サブクラス」などと呼ばれています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# 親クラス定義
class ParentClass:
def add(self,x,y): # 加算関数
return x+y
def pi(self): # 円周率(精度良くありません)
return 3.14
# 子クラス定義(ParentClassを継承しています)
class ChildClass(ParentClass): #()の中に継承したいクラス名を記述すると継承できます
def sub(self,x,y): # subメソッドを追加
return x-y
def pi(self): # piメソッドをオーバーライド
return 3.14159265358979 # 精度を上げます
op = ParentClass() # 親クラスのインスタンス作成
oc = ChildClass() # 子クラスのインスタンス作成
print("op.add =",op.add(2,3))
print("op.pi =",op.pi())
print("oc.add =",oc.add(2,3))
print("oc.sub =",oc.sub(2,3))
print("oc.pi =",oc.pi())
|
Pythonのsuper関数の使い方
Pythonのsuper関数はPython3とPython2で書き方が異なります。ここではPython3の書き方で解説します。
まずはsuper関数を使ったサンプルプログラムを紹介します。それと2つのクラスを継承したときのsuper関数の動作を解説します。
super関数を使ったサンプルプログラム
Pythonのsuper関数を使うときというのは、継承する(オーバーライドする)メソッドの機能を拡張したいときなどでしょう。単純な置き換えで機能拡張しようとすると、親クラスのメソッドのコードも含めて記述する必要がありますが、親クラスのメソッドを呼び出すことで、その部分のコードを書く必要がなくなります。
下記にsuper関数を使って機能拡張したメソッドのサンプルプログラムを示します。2つあるメソッドともsuper関数を使って機能拡張しています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# Python3で動作させてください。
# Windows10とPython3.9.1で動作確認しました。
class Info: # 親クラスInfo
def __init__(self,weight,height): # コンストラクタ(体重と身長の引数が必要)
self.weight = weight # 体重
self.height = height # 身長
def prn_dat(self): # 体重と身長を表示するメソッド
print("体重 = {0}, 身長 = {1}".format(self.weight,self.height))
class PersonalInfo(Info): # 子クラス(Infoクラスを継承)
def __init__(self,name,age,weight,height): # コンストラクタ(名前、年齢、体重、身長)
super().__init__(weight,height) # super関数で親クラス(Info)のコンストラクタを呼び出して初期化
self.name = name # 名前
self.age = age # 年齢
def prn_dat(self): # 個人情報を表示するメソッド
print("名前 = {0}, 年齢 = {1}".format(self.name,self.age)) # 名前と年齢を表示
super().prn_dat() # 親クラスのprn_datメソッドを呼び出して体重と身長を表示
op = PersonalInfo("サンプル太郎",23,60.3,171.5) # インスタンスを作成&個人情報を設定
op.prn_dat() # 設定した個人情報を表示
|
2つのクラスを継承したときのsuper関数の動作
2つのクラスを継承したとき、どちらのクラスにも同じ名前のメソッドがあるとsuper関数は正しく選択することができません。
Pythonの探索アルゴリズムが分かっていれば使える可能性もありますが、不具合の原因になることも想定しましょう。そういった理由でsuper関数は使えない(使わない)ので継承したクラスのメソッドを直接呼び出す必要があります。
以下のサンプルプログラムは、親クラス2つ(Info、 Info2)を持つ子クラス(PersonalInfo)からsuper関数を使わないで直接親クラスのメソッドを呼び出しているサンプルプログラムです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
# Python3で動作させてください。
# Windows10とPython3.9.1で動作確認しました。
class Info: # 親クラスInfo
def __init__(self,weight,height): # コンストラクタ(体重と身長の引数が必要)
self.weight = weight # 体重
self.height = height # 身長
def prn_dat(self): # 体重と身長を表示するメソッド
print("体重 = {0}, 身長 = {1}".format(self.weight,self.height))
class Info2: # 親クラスInfo2
def __init__(self,hobby,feats): # コンストラクタ(趣味と特技の引数が必要)
self.hobby = hobby
self.feats = feats
def prn_dat(self): # 趣味と特技を表示するメソッド
print("趣味 = {0}, 特技 = {1}".format(self.hobby,self.feats))
class PersonalInfo(Info,Info2): # 子クラス(Infoクラスを継承)
def __init__(self,name,age,weight,height,hobby,feats): # (名前、年齢、体重、身長、趣味、特技)
Info.__init__(self,weight,height) # 親クラス(Info)のコンストラクタを呼び出して初期化
Info2.__init__(self,hobby,feats) # 親クラス(Info2)のコンストラクタを呼び出して初期化
self.name = name # 名前
self.age = age # 年齢
def prn_dat(self): # 個人情報を表示するメソッド
print("名前 = {0}, 年齢 = {1}".format(self.name,self.age)) # 名前と年齢を表示
Info.prn_dat(self) # 親クラスInfoのprn_datメソッドを呼び出して体重と身長を表示
Info2.prn_dat(self) # 親クラスInfo2のprn_datメソッドを呼び出して趣味と特技を表示
op = PersonalInfo("サンプル太郎",23,60.3,171.5,"音楽鑑賞","けん玉") # インスタンスを作成&個人情報を設定
op.prn_dat() # 設定した個人情報を表示
|
- システム
エンジニア - 2つのクラスを継承したときにどちらのクラスにも同じ名前のメソッドがあるとsuper関数は正しく選択できないのですか。
- プロジェクト
マネージャー - その通りです。2つのクラスを継承したときどちらのクラスにも同じ名前のメソッドがあるときは継承したクラスのメソッドを直接呼び出す必要があります。
最後に
Pythonはクラスの多重継承ができるプログラミング言語です。多重継承は、便利な機能です。上手く活用すれば多重継承のときでもsuper関数は「使える関数」になるでしょう。実際にご自身でコードを書いて理解を深めて下さい。
FEnet.NETナビ・.NETコラムは株式会社オープンアップシステムが運営しています。
株式会社オープンアップシステムはこんな会社です
秋葉原オフィスには株式会社オープンアップシステムをはじめグループのIT企業が集結!
数多くのエンジニアが集まります。
-
スマホアプリから業務系システムまで
スマホアプリから業務系システムまで開発案件多数。システムエンジニア・プログラマーとしての多彩なキャリアパスがあります。
-
充実した研修制度
毎年、IT技術のトレンドや社員の要望に合わせて、カリキュラムを刷新し展開しています。社内講師の丁寧なサポートを受けながら、自分のペースで学ぶことができます。
-
資格取得を応援
スキルアップしたい社員を応援するために資格取得一時金制度を設けています。受験料(実費)と合わせて資格レベルに合わせた最大10万円の一時金も支給しています。
-
東証プライム上場企業グループ
オープンアップシステムは東証プライム上場「株式会社オープンアップグループ」のグループ企業です。
安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。
株式会社オープンアップシステムに興味を持った方へ
株式会社オープンアップシステムでは、開発系エンジニア・プログラマを募集しています。
年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
まずは話だけでも聞いてみたい場合もOK。お気軽にご登録ください。
Python新着案件New Job
-
マルチロガーソフト開発/東京都豊島区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都豊島区(池袋駅) -
マルチロガーソフト開発/東京都豊島区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都豊島区(池袋駅) -
商品化予定の振動センサーの運用保守/Python/東京都都内/【WEB面談可】
月給50万~60万円東京都都内(-駅) -
商品化予定の振動センサーの可視化UI開発のテスター/Python/東京都都内/【WEB面談可】
月給25万~35万円東京都都内(-駅) -
商品化予定の振動センサーの運用保守/Python/東京都都内/【WEB面談可】
月給50万~60万円東京都都内(-駅) -
商品化予定の振動センサーの可視化UI開発のテスター/Python/東京都都内/【WEB面談可】
月給25万~35万円東京都都内(-駅)