Python デコレータ徹底解説:基礎から応用までわかりやすく解説!

Python デコレータ徹底解説:基礎から応用までわかりやすく解説!

記事の文字数:1163

Pythonのデコレータは、関数やクラスの振る舞いを柔軟に拡張できる便利な機能です。本記事では、初心者でも理解しやすいコード例と実行結果を交えて、デコレータの基本的な仕組みから、実践的な応用例まで詳しく解説します。Pythonの開発を効率化し、可読性の高いコードを書けるようになりましょう!


スポンサーリンク

Pythonのデコレータ(Decorator)は、関数やクラスの振る舞いを変更するための機能です。デコレータを使うことで、コードの再利用性を高め、簡潔かつ直感的な記述が可能になります。

デコレータの使い方

デコレータは、関数を引数として受け取り、新しい関数を返す高階関数です。これにより、関数の振る舞いを変更できます。

デコレータは@デコレータ名という形で指定します。基本的なデコレータの使い方を見てみましょう。

実装例

decorator-ex-01.py
# デコレータの定義
def my_decorator(func):
def wrapper():
print("処理開始")
func()
print("処理終了")
return wrapper
# デコレータを適用
@my_decorator
def my_function():
print("メインの処理")
my_function()

実行結果

実行結果
処理開始
メインの処理
処理終了

@my_decorator を指定し、関数の前後で追加の処理を実行することを確認できました。

デコレータの応用

デコレータは、関数の前後に特定の処理を挿入するのに便利で、例えばログの記録、実行時間の計測、認証のチェックなどに活用されます。また、コードの可読性を向上させる役割も果たします。

引数を持つ関数に対応

デコレータを適用する関数が引数を取る場合、*args**kwargs を使用して可変長引数に対応できます。これにより、どんな関数にも柔軟に適用可能になります。

decorator-ex-02.py
def my_decorator(func):
def wrapper(*args, **kwargs):
print("処理開始")
result = func(*args, **kwargs)
print(result)
print("処理終了")
return result
return wrapper
@my_decorator
def add(a, b):
return a + b
add(3, 5)

処理開始と処理終了の間でadd関数の結果(3+5=8)が表示されることを確認できました。

実行結果
処理開始
8
処理終了

複数のデコレータを適用

複数のデコレータを組み合わせることで、関数に複数の装飾を適用できます。

decorator-ex-03.py
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
@decorator2
def say_hello():
print("Hello!")
say_hello()

以下の通り、デコレータは上から順に適用されます。

実行結果
デコレータ1実行
デコレータ2実行
Hello!

クラスに適用する

デコレータはクラスにも適用でき、クラスの振る舞いを変更できます。

decorator-ex-04.py
def class_decorator(cls):
class NewClass(cls):
def new_method(self):
return "追加メソッド"
return NewClass
@class_decorator
class MyClass:
def original_method(self):
return "元のメソッド"
obj = MyClass()
print(obj.original_method())
print(obj.new_method())

元のメソッドに加えて、追加メソッドの実行ができるようになります。

実行結果
元のメソッド
追加メソッド

デコレータの様々な実用例

ロギング

デコレータを使って関数の実行ログを記録し、デバッグや動作確認に役立てることができます。

decorator-ex-05.py
import functools
def log_decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print(f"関数 {func.__name__} を実行します")
return func(*args, **kwargs)
return wrapper
@log_decorator
def greet(name):
print(f"こんにちは、{name}!")
greet("太郎")

以下の通り、こんにちはの前に実行開始ログが出力されます。

実行結果
関数 greet を実行します
こんにちは、太郎!

実行時間の計測

関数の実行時間を計測するデコレータの例です。処理のパフォーマンス測定に利用することができます。

decorator-ex-06.py
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_decorator
def slow_function():
time.sleep(2)
print("処理が完了しました")
slow_function()
実行結果
処理が完了しました
実行時間: 2.0016653537750244

キャッシュ

functools.lru_cache を利用して関数の結果をキャッシュし、パフォーマンスを向上させることができます。

decorator-ex-07.py
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ユーザのみ許可しています。

decorator-ex-08.py
def auth_decorator(func):
def wrapper(user):
if user != "admin":
print("アクセス拒否")
return
return func(user)
return wrapper
@auth_decorator
def secret_function(user):
print("機密情報を表示")
print("▼guestの場合")
secret_function("guest")
print("▼adminの場合")
secret_function("admin")
実行結果
▼guestの場合
アクセス拒否
▼adminの場合
機密情報を表示

シングルトンパターン

シングルトンパターンを実装し、インスタンスの重複生成を防ぎます。

decorator-ex-10.py
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
@singleton
class Database:
def __init__(self):
print("データベース接続")
db1 = Database()
db2 = Database()
print(db1 is db2) # True
実行結果
データベース接続
True

まとめ

デコレータを活用すると、コードの再利用性が向上し、保守性が向上します。
デコレータは便利なツールであり、さまざまな場面で活用できます。上手に使いこなし、より効率的なコードを書きましょう!


以上で本記事の解説を終わります。
よいITライフを!
スポンサーリンク
Scroll to Top