はじめに
Pythonのデコレータは、既存の関数やクラスを修正したり拡張したりする強力な機能です。本記事では、デコレータの基本的な概念から実践的な使用例まで、段階的に解説していきます。
デコレータとは
デコレータは、他の関数を引数として受け取り、その動作を変更または拡張する関数です。簡単に言えば、既存の関数をラップして新しい機能を追加する方法です。
基本的なデコレータの書き方
まずは、シンプルなデコレータの例を見てみましょう。
def simple_decorator(func):
def wrapper():
print("関数が呼び出される前")
func()
print("関数が呼び出された後")
return wrapper
@simple_decorator
def say_hello():
print("こんにちは!")
say_hello()
実行結果:
関数が呼び出される前
こんにちは!
関数が呼び出された後
この例では、simple_decorator
がsay_hello
関数をラップし、関数の前後に追加のメッセージを表示します。
引数を持つ関数のデコレート
引数を持つ関数にデコレータを適用する場合は、以下のように書きます。
def log_args(func):
def wrapper(*args, **kwargs):
print(f"呼び出された引数: {args}, {kwargs}")
return func(*args, **kwargs)
return wrapper
@log_args
def add(a, b):
return a + b
result = add(3, 5)
print(f"結果: {result}")
実行結果:
呼び出された引数: (3, 5), {}
結果: 8
この例では、log_args
デコレータが関数の引数をログ出力します。
デコレータに引数を渡す
デコレータ自体に引数を渡したい場合は、以下のように実装します。
def repeat(times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(times=3)
def greet(name):
print(f"こんにちは、{name}さん!")
greet("太郎")
実行結果:
こんにちは、太郎さん!
こんにちは、太郎さん!
こんにちは、太郎さん!
この例では、repeat
デコレータが関数を指定回数繰り返し実行します。
実践的な使用例
1. 実行時間の計測
import time
def measure_time(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__}の実行時間: {end_time - start_time:.4f}秒")
return result
return wrapper
@measure_time
def slow_function():
time.sleep(2)
print("処理完了")
slow_function()
実行結果:
処理完了
slow_functionの実行時間: 2.0021秒
2. キャッシュ(メモ化)
def memoize(func):
cache = {}
def wrapper(*args):
if args in cache:
return cache[args]
result = func(*args)
cache[args] = result
return result
return wrapper
@memoize
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(100))
実行結果:
354224848179261915075
この結果は瞬時に出力されます。キャッシュがない場合、この計算には非常に長い時間がかかります。
まとめ
デコレータを使うことで、コードの再利用性が高まり、関数の機能を柔軟に拡張できます。本記事で紹介した例を参考に、自分のプロジェクトでデコレータを活用してみてください。デバッグ、ログ出力、性能測定など、様々な場面でデコレータが役立つはずです。
参考文献
- Python公式ドキュメント: 関数定義
- Real Python: Primer on Python Decorators