【国内正規品】MonsGeek(モンスギーク) FUN60 Pro SP 有線モデル HEセンサー 0.01mm ラピッドトリガー対応 磁気スイッチ Akko Glare Magnetic Switch 英語配列 テンキーレス サイドプリント 有線8K ホットスワップ SnapKeys (SOCD)対応 ARGB対応 高コスパ ゲーミングキーボード Black
¥5,980 (2025年4月25日 13:07 GMT +09:00 時点 - 詳細はこちら価格および発送可能時期は表示された日付/時刻の時点のものであり、変更される場合があります。本商品の購入においては、購入の時点で当該の Amazon サイトに表示されている価格および発送可能時期の情報が適用されます。)
概要
Decorator(デコレーター)パターンは、
既存のオブジェクトや関数の構造を変更せずに、新しい振る舞いを動的に追加する構造的デザインパターンである。
Pythonでは @decorator
構文によって言語レベルでサポートされており、
関数・メソッド・クラスの振る舞いをシームレスに拡張する非常に重要な機構のひとつである。
1. なぜDecoratorが必要か?
❌ 既存関数のコードを変更して機能を追加
def process():
# ログ出力を追加したい
print("Start")
... # 処理本体
print("End")
→ コードの可読性・保守性が低下し、再利用も困難
✅ デコレーターで機能を“包む”
@with_logging
def process():
...
→ 本体に手を加えずに、任意の前後処理を柔軟に追加可能
2. 関数デコレーターの構造
✅ デコレーター関数の基本形
def with_logging(func):
def wrapper(*args, **kwargs):
print(f"[LOG] Start {func.__name__}")
result = func(*args, **kwargs)
print(f"[LOG] End {func.__name__}")
return result
return wrapper
✅ 使用例
@with_logging
def compute():
print("Computing...")
compute()
[LOG] Start compute
Computing...
[LOG] End compute
3. デコレーターの応用
✅ 引数付きデコレーター(ファクトリ形式)
def with_prefix(prefix):
def decorator(func):
def wrapper(*args, **kwargs):
print(f"{prefix} → {func.__name__}")
return func(*args, **kwargs)
return wrapper
return decorator
@with_prefix(">>>")
def greet():
print("Hello")
greet()
✅ functools.wraps
による関数情報の保持
from functools import wraps
def with_logging(func):
@wraps(func)
def wrapper(*args, **kwargs):
...
return wrapper
→ docstring, 関数名などのメタ情報を保持可能に
4. クラスベースのデコレーター
class Timer:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
import time
start = time.time()
result = self.func(*args, **kwargs)
end = time.time()
print(f"{self.func.__name__} took {end - start:.4f}s")
return result
@Timer
def work():
sum(range(10**6))
work()
5. 実務ユースケース
✅ 関数トレーシング・ログ出力
→ 実行タイミング、引数、戻り値の記録
✅ 認証・認可制御(Flaskなどでよく利用)
@app.route("/admin")
@requires_admin
def admin_panel():
...
✅ リトライ機構やキャッシュ制御
@retry(times=3)
def unstable_operation():
...
✅ テストコードにおけるセットアップ装飾
@pytest.mark.parametrize(...)
def test_case(...):
...
6. よくある誤用と対策
❌ wrapperで戻り値を返さない
→ ✅ 必ず return func(...)
を忘れずに書くことで、オリジナルの機能を壊さない
❌ functools.wraps を使わないことで関数情報が破損
→ ✅ デバッグ性を高めるために、@wraps は常に付けるのが基本
❌ 本体と無関係な機能を過剰に追加
→ ✅ デコレーターは「責務の周辺」に限定し、1つのデコレーターに1つの機能
結語
Decoratorパターンとは、“拡張を内包し、振る舞いを優しく包み込む”設計技法である。
- 実装本体を変えずに、新しい機能を動的に付加できる
- Pythonにおいては関数・クラスレベルでの応用が可能で、テスト性・柔軟性・再利用性を劇的に高める
- 設計の明瞭さと実装の疎結合性を両立できる、非常に実用的な構造
Pythonicとは、“変えずに加える”柔らかさを設計することであり、
Decoratorパターンはその柔軟な包容力を、コード全体に優雅に浸透させる。