開発の初期段階では、全体の設計を行うために「関数名やクラス名だけを定義しておき、中身の処理は後で実装したい」という場面が多々あります。
しかし、Pythonはインデント(字下げ)によってブロックを管理しているため、関数の中身を空のままにしておくと IndentationError(インデントエラー)が発生し、プログラムを実行できません。
この記事では、Pythonで処理を「何もしない」まま定義しておくための pass 文と、実行時に未実装であることを明示的に通知する NotImplementedError について解説します。
1. pass 文:何もしないことを明示する
pass は、Pythonにおいて「文法上、何かを記述する必要があるが、実行する処理は何もない」場合に使用する構文です。
これを記述しておくことで、空の関数やクラスをエラーなく定義できます。
構文:
def 関数名():
pass
具体的な使用例
データ分析ツールの設計段階を想定し、データの読み込み、加工、保存という3つの関数を定義します。現時点では枠組みだけを作り、中身は空にしておきます。
def load_raw_data(file_path):
"""
ファイルを読み込む関数(後で実装)
"""
pass
def process_data(data):
"""
データを加工する関数(後で実装)
"""
pass
def save_report(result):
"""
レポートを保存する関数(後で実装)
"""
pass
# --- メイン処理 ---
print("処理を開始します。")
# 関数を呼び出してもエラーにはならず、何も起きずに終了する
load_raw_data("data.csv")
process_data(None)
save_report(None)
print("処理が完了しました。")
実行結果:
処理を開始します。
処理が完了しました。
このように、pass を記述しておけば、中身が空であってもプログラム全体を実行可能です。開発中のプレースホルダー(仮置き)として非常に便利です。
2. NotImplementedError:実行時にエラーを通知する
pass 文は単に処理をスキップしますが、場合によっては「この機能はまだ使えません」と明示的にエラーを出したいこともあります。
その場合は、pass の代わりに例外 NotImplementedError を発生(raise)させます。
構文:
def 関数名():
raise NotImplementedError("この機能は未実装です")
具体的な使用例
将来的に実装予定の「クラウド同期機能」を呼び出した際に、エラーを発生させる例です。
def sync_to_cloud():
# まだ実装されていないため、呼び出されたらエラーにする
raise NotImplementedError("クラウド同期機能は現在開発中です。")
print("同期処理を開始します...")
try:
sync_to_cloud()
except NotImplementedError as e:
print(f"エラー: {e}")
print("処理を中断しました。")
実行結果:
同期処理を開始します...
エラー: クラウド同期機能は現在開発中です。
処理を中断しました。
これにより、実装を忘れたまま関数を使用してしまった場合に、即座に気づくことができます。
3. Ellipsis (...) を使う方法
Python 3では、pass の代わりに ... (Ellipsis: 省略記号) を記述することも可能です。機能的には pass とほぼ同じですが、型ヒント(Type Hints)のスタブファイルなどでよく見られる記法です。
def calculate_metric(value):
... # pass と同じ意味で、何もしない
calculate_metric(100)
通常の開発では pass が使われることが一般的ですが、より簡潔に記述したい場合に使用されます。
まとめ
Pythonで未実装の関数やクラスを定義するには、状況に応じて以下の方法を使い分けます。
pass文: とりあえず枠組みだけ作り、エラーなく実行できるようにしたい場合。(最も一般的)raise NotImplementedError: 関数が呼び出された際に、「未実装である」というエラーを発生させたい場合。...(Ellipsis):passの代わりとして簡潔に記述したい場合。
