
スポンサーリンク
Pythonのデコレータ(Decorator)は、関数やクラスの振る舞いを変更するための機能です。デコレータを使うことで、コードの再利用性を高め、簡潔かつ直感的な記述が可能になります。
デコレータの使い方
デコレータは、関数を引数として受け取り、新しい関数を返す高階関数です。これにより、関数の振る舞いを変更できます。
デコレータは@デコレータ名
という形で指定します。基本的なデコレータの使い方を見てみましょう。
実装例
# デコレータの定義def my_decorator(func): def wrapper(): print("処理開始") func() print("処理終了") return wrapper
# デコレータを適用@my_decoratordef my_function(): print("メインの処理")
my_function()
実行結果
処理開始メインの処理処理終了
@my_decorator
を指定し、関数の前後で追加の処理を実行することを確認できました。
デコレータの応用
デコレータは、関数の前後に特定の処理を挿入するのに便利で、例えばログの記録、実行時間の計測、認証のチェックなどに活用されます。また、コードの可読性を向上させる役割も果たします。
引数を持つ関数に対応
デコレータを適用する関数が引数を取る場合、*args
と **kwargs
を使用して可変長引数に対応できます。これにより、どんな関数にも柔軟に適用可能になります。
def my_decorator(func): def wrapper(*args, **kwargs): print("処理開始") result = func(*args, **kwargs) print(result) print("処理終了") return result return wrapper
@my_decoratordef add(a, b): return a + b
add(3, 5)
処理開始と処理終了の間でadd関数の結果(3+5=8)が表示されることを確認できました。
処理開始8処理終了
複数のデコレータを適用
複数のデコレータを組み合わせることで、関数に複数の装飾を適用できます。
def decorator1(func): def wrapper(*args, **kwargs): print("デコレータ1実行") return func(*args, **kwargs) return wrapper
def decorator2(func): def wrapper(*args, **kwargs): print("デコレータ2実行") return func(*args, **kwargs) return wrapper
@decorator1@decorator2def say_hello(): print("Hello!")
say_hello()
以下の通り、デコレータは上から順に適用されます。
デコレータ1実行デコレータ2実行Hello!
クラスに適用する
デコレータはクラスにも適用でき、クラスの振る舞いを変更できます。
def class_decorator(cls): class NewClass(cls): def new_method(self): return "追加メソッド" return NewClass
@class_decoratorclass MyClass: def original_method(self): return "元のメソッド"
obj = MyClass()print(obj.original_method())print(obj.new_method())
元のメソッドに加えて、追加メソッドの実行ができるようになります。
元のメソッド追加メソッド
デコレータの様々な実用例
ロギング
デコレータを使って関数の実行ログを記録し、デバッグや動作確認に役立てることができます。
import functools
def log_decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): print(f"関数 {func.__name__} を実行します") return func(*args, **kwargs) return wrapper
@log_decoratordef greet(name): print(f"こんにちは、{name}!")
greet("太郎")
以下の通り、こんにちは
の前に実行開始ログが出力されます。
関数 greet を実行しますこんにちは、太郎!
実行時間の計測
関数の実行時間を計測するデコレータの例です。処理のパフォーマンス測定に利用することができます。
import time
def timer_decorator(func): def wrapper(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) end_time = time.time() print(f"実行時間: {end_time - start_time} 秒") return result return wrapper
@timer_decoratordef slow_function(): time.sleep(2) print("処理が完了しました")
slow_function()
処理が完了しました実行時間: 2.0016653537750244 秒
キャッシュ
functools.lru_cache
を利用して関数の結果をキャッシュし、パフォーマンスを向上させることができます。
from functools import lru_cache
@lru_cache(maxsize=5)def fibonacci(n): if n < 2: return n return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10))
55
認証
認証処理を簡単に追加できます。以下例ではadminユーザのみ許可しています。
def auth_decorator(func): def wrapper(user): if user != "admin": print("アクセス拒否") return return func(user) return wrapper
@auth_decoratordef secret_function(user): print("機密情報を表示")
print("▼guestの場合")secret_function("guest")print("▼adminの場合")secret_function("admin")
▼guestの場合アクセス拒否▼adminの場合機密情報を表示
シングルトンパターン
シングルトンパターンを実装し、インスタンスの重複生成を防ぎます。
def singleton(cls): instances = {}
def get_instance(*args, **kwargs): if cls not in instances: instances[cls] = cls(*args, **kwargs) return instances[cls] return get_instance
@singletonclass Database: def __init__(self): print("データベース接続")
db1 = Database()db2 = Database()print(db1 is db2) # True
データベース接続True
まとめ
デコレータを活用すると、コードの再利用性が向上し、保守性が向上します。
デコレータは便利なツールであり、さまざまな場面で活用できます。上手に使いこなし、より効率的なコードを書きましょう!
以上で本記事の解説を終わります。
よいITライフを!