オーバーライドでは親クラスのメンバーが引き継がれる
はじめに
本日の仕事でPythonETLの社内共通テンプレートのオーバーライドを行い、親クラスのメソッドや変数を子クラスで引き継いだ。
特に何もしなければ、コンストラクタで定義した初期値などが子クラスに引き継がれる。
こういったことについて書いていきたい。
GPTに出してもらったソースコード
以下のソースコードをGPTに生成してもらった。
base_etl.py
class BaseETL:
def __init__(self):
self.source_path = "/data/input.csv"
self.target_table = "default_table"
self.batch_id = "0000"
print(f"[BaseETL] 初期化: source={self.source_path}, target={self.target_table}")
def extract(self):
print(f"[BaseETL] extract from {self.source_path}")
def transform(self):
print("[BaseETL] default transform")
def load(self):
print(f"[BaseETL] load into {self.target_table}")
def run(self):
self.extract()
self.transform()
self.load()
custom_etl.py
from base_etl import BaseETL
class CustomETL(BaseETL):
def __init__(self):
super().__init__() # 親の初期化処理を呼ぶ(source_pathなどを継承)
self.target_table = "custom_table" # 一部の初期値だけ変更
def transform(self):
print("[CustomETL] 独自の変換処理")
# 実行
if __name__ == "__main__":
etl = CustomETL()
etl.run()
このソースコードの処理を追っていこう。
その過程で、オーバーライドについての理解を深めていく。
フォルダ構成
フォルダ構成はこちら。__pycache__は気にしないで欲しい。

templateの上の階層には、Pythonの仮想環境のvenvがある。

custom_etl.pyの実行結果

(.venv) hiroki@shibatahiroshitakanoiMac Python % /Users/hiroki/Downloads/Python/.venv/bin/python /Users/hiroki/Downloads/Python/override/template/custom_etl.py
[BaseETL] 初期化: source=/data/input.csv, target=default_table
[BaseETL] extract from /data/input.csv
[CustomETL] 独自の変換処理
[BaseETL] load into custom_table
処理の流れ
- CustomETLクラスのインスタンス生成
- runメソッドの実行
- extractメソッドの実行
- transformメソッドの実行
- loadメソッドの実行
3、4、5は2のrunメソッドで実行している。
なにはともあれ、細かく見ていこう。
その方が理解が深まる。
CuntomETLクラスのインスタンス生成
custom_etl.py

12行目はPythonお決まりのmainを実行するための条件文(もう少し解像度高く説明できるようになりたい)。
なにはともあれ、この後にメイン処理の関数を記述する。
13行目で、CustomETLクラスのインスタンスをetlに代入している。
CustomETLクラス

base_etl.pyのBaseETLクラスを継承している。
コンストラクタと、transformの処理がある。
コンストラクタでは、親の初期化処理を呼んでいる。
親の初期化処理

source_path、target_table、batch_idを定義して、「[BaseETL] 初期化: source=/data/input.csv, target=default_table」をコンソールに出力している。
親の初期化処理が完了した後は、target_tableの値を上書きしている。

これで、CustomETLの初期化処理は終了。次に、runメソッドが呼ばれる。

runメソッドの実行

runメソッド

runメソッドでは、3つの関数を実行している。
extractメソッドの実行

「[BaseETL] extract from /data/input.csv」をコンソールに出力している。
source_pathには、BaseETLで初期化した値が入っている。
transformメソッドの実行
次に、tranformメソッドが実行される。

ここで実行されるtransformメソッドは、BaseETLではなく、CuntomETLのメンバ関数。

コンソールに「[CustomETL] 独自の変換処理」と出力される。
loadメソッドの実行
最後に、loadメソッドが実行される。

CustomETLで何も手を加えていないので、BaseETLのloadメソッドがそのまま実行される。

そしてコンソールに「[BaseETL] load into custom_table」と出力される。
ここで注意が必要なのが、custom_tableという箇所。
BaseETLで定義したdefault_tableは、CustomETLで上書きされている。

そのため、default_tableではなく、custom_tableが出力されている。
本日の実務で深まった理解
「子クラスでコンストラクタに処理を追加したい。」「親クラスのコンストラクタの処理は引き継ぎたい」という場合、super().__init__()を使用する。
親クラスの内容をそのまま持ってきても構わなければ、コンストラクタを書く必要はない。
コメントを残す