Pythonにおいて処理の分岐を記述する際、多くの場合if
文が使用されます。しかし、条件分岐が多くなると、コードが冗長かつ読みにくくなる傾向があります。
本記事では、if
文を使用せずに処理を分岐させる手法として、辞書(dict
)を用いたディスパッチ(dispatch)パターンを紹介します。
if
文による分岐の実例とそのメリット・デメリット
def handle_command(command: str) -> None:
if command == "start":
print("Starting")
elif command == "stop":
print("Stopping")
elif command == "pause":
print("Pausing")
else:
print("Unknown command")
メリット
- 誰にでも読みやすく、直感的に理解できる。
- 小規模な分岐に適している。
デメリット
- 分岐が多くなると可読性が低下する。
- 各条件における処理が長くなると、関数全体が肥大化する。
- 処理内容の変更・拡張が煩雑になる。
dict
によるディスパッチの基本構文と実例
ディスパッチパターンでは、キーを条件、値を関数(または処理)とした辞書を構築します。
def start():
print("Starting")
def stop():
print("Stopping")
def pause():
print("Pausing")
def unknown():
print("Unknown command")
command_map: dict[str, Callable[[], None]] = {
"start": start,
"stop": stop,
"pause": pause,
}
def handle_command(command: str) -> None:
command_map.get(command, unknown)()
メリット
- 可読性と拡張性に優れる。
- 各処理が関数として分離されているため、テストや再利用が容易。
- 条件の増減が辞書の編集のみで済む。
デメリット
- 初学者には一見して分かりにくい場合がある。
- 引数の受け渡しに工夫が必要な場合がある。
dict
ディスパッチで引数を渡すには
引数付きの関数をディスパッチする場合、ラムダ式やfunctools.partial
を利用します。
from functools import partial
def greet(name: str) -> None:
print(f"Hello, {name}!")
def farewell(name: str) -> None:
print(f"Goodbye, {name}!")
command_map: dict[str, Callable[[], None]] = {
"hello": partial(greet, "Alice"),
"bye": partial(farewell, "Bob"),
}
def handle_command(command: str) -> None:
command_map.get(command, lambda: print("Unknown command"))()
このように、事前に引数をバインドしておくことで、ディスパッチ対象の関数に引数を渡すことができます。
辞書によるディスパッチは、Pythonらしい簡潔さと柔軟性を兼ね備えた手法です。特に処理が増える場面では、if
文よりもメンテナンス性に優れる点が多く見られます。今後のコーディングにおいて、有効な選択肢の一つとしてぜひ活用を検討してみてください。