【Python】デコレータ徹底解説|基礎からわかりやすく解説!

【Python】デコレータ徹底解説|基礎からわかりやすく解説!

当ページのリンクには広告が含まれています。

記事の文字数:1603

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()

上記、10行目で @my_decorator を指定し、my_functionを引数として渡します。

デコレータの実行結果

実行結果
$ python decorator-ex-01.py
処理開始
メインの処理
処理終了

上記の通り、my_function関数の前後で、処理開始・処理終了の追加の処理が実行されることを確認できました。

デコレータの応用的な使い方

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

引数を持つ関数にデコレータを適用

デコレータを適用する関数が引数を取る場合、*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)が表示されることを確認できました。

実行結果
$ python decorator-ex-02.py
処理開始
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()

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

実行結果
python decorator-ex-03.py
デコレータ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())

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

実行結果
python decorator-ex-04.py
元のメソッド
追加メソッド

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

デコレータでロギングを行う

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

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("太郎")

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

実行結果
python decorator-ex-05.py
関数 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()
実行結果
python decorator-ex-06.py
処理が完了しました
実行時間: 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))
実行結果
python decorator-ex-07.py
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")
実行結果
python decorator-ex-08.py
▼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
実行結果
python decorator-ex-09.py
データベース接続
True

デコレータまとめ

  • デコレータは@デコレータ名で指定する。
  • デコレータは関数やクラスに指定できる。
  • デコレータを適用する関数が引数を取る場合、*args**kwargsを使用して可変長引数に対応できる。
  • デコレータを利用することでログの記録、実行時間の計測、認証のチェックなどに活用できる。

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

プログラミング学習者にお勧めの書籍

独学で身につけるためのプログラミング学習術: Ver.5

新品価格
¥980から
(2025/4/22 21:15時点)


以上で本記事の解説を終わります。
よいITライフを!
Scroll to Top