Python でデコレータを作成して使用する方法
Python でデコレータを作成して適用する方法を学びます。ラップ関数、動作の変更、引数の処理、ラップによるメタデータの保持をマスターします。
概要
デコレータは Python の最もエレガントで強力な構文機能の 1 つで、コードを永続的に変更せずに関数またはクラスの動作を変更できます。これらは、実行時間のログ記録、ユーザー認証の強制、結果のキャッシュ (メモ化)、API エンドポイントの監査など、横断的な問題に広く使用されています。
内部では、デコレーターは別の関数を引数として受け取り、カスタム ロジックを挿入する入れ子になったラッパー関数を定義し、このラッパー関数を返す高階関数です。 Python は、関数にデコレータを適用するための「@」記号を使用した簡潔な省略構文を提供し、関数を視覚的にエレガントにします。
デコレータを作成するときは、通常、デコレータ関数で任意の数の位置引数およびキーワード引数をサポートする必要があります。これを実現するには、`*args` と `**kwargs` を受け入れてターゲット関数に渡すようにネストされたラッパー関数を設計します。さらに、元の関数の docstring と名前のメタデータを保存するには、ラッパー関数で `functools.wraps` を使用する必要があります。
コードと実行の出力
このスクリプトは、ロギング デコレータの作成と、入力、出力、およびメタデータを検査する関数のラップを示します。
from functools import wraps
# 1. Defining a decorator
def log_execution(func):
@wraps(func) # Preserves original function metadata
def wrapper(*args, **kwargs):
print(f"[Log] Calling function: {func.__name__} with args: {args}")
result = func(*args, **kwargs)
print(f"[Log] Finished {func.__name__}. Result: {result}")
return result
return wrapper
# 2. Applying the decorator using @ syntax
@log_execution
def add_numbers(a, b):
"""Adds two numbers and returns the sum."""
return a + b
# 3. Invoking the decorated function
sum_result = add_numbers(15, 25)
print("Sum Result:", sum_result)
# Verifying metadata preservation
print("Docstring preserved:", add_numbers.__doc__)[Log] Calling function: add_numbers with args: (15, 25)
[Log] Finished add_numbers. Result: 40
Sum Result: 40
Docstring preserved: Adds two numbers and returns the sum.段階的な実装
- ターゲット関数を引数として受け取る外部デコレータ関数を定義します。
- @functools.wraps(func) をインポートしてネストされたラッパー関数に適用して、元のメタデータを保護します。
- 入力変数をキャプチャし、ロジックを挿入し、ターゲット関数を呼び出すために、wrapper(*args, **kwargs) を実装します。
- デコレーターヘッダーブロックからラッパー関数オブジェクトを返します。
- @decorator_name を使用してデコレータをターゲット関数シグネチャのすぐ上に適用します。
よくある質問
デコレータ内で @functools.wraps が必要なのはなぜですか?
ラップがないと、装飾された関数は元のアイデンティティを失い (その __name__ 属性と __doc__ 属性は、ネストされたラッパー関数の属性に置き換えられます)、デバッグとコードのイントロスペクションが困難になります。
1 つの関数に複数のデコレータを適用できますか?
はい!複数の @ 行を重ねて配置することで、デコレータをチェーンできます。 Python はこれらを下から上に適用します (関数定義に最も近いものが最初に実行されます)。
関連トピック
推奨される Python リソース
関連するインタラクティブなチュートリアル、チートシート、コード比較で知識を深めてください。
Python の変数とデータ型の説明
Python 変数と主要なデータ型 (文字列、整数、浮動小数点数、ブール値) を理解します。 Python でのメモリ割り当ての完全な初心者ガイド。
Python 辞書メソッドのチートシート
Python の辞書メソッドを学習します。キーと値のペアの挿入、取得、更新、チェックに関する完全なリファレンス ガイド。
Python と JavaScript: どちらのプログラミング言語が最適ですか?
Python と JavaScript の包括的な比較。構文の違い、パフォーマンス、使用例 (バックエンドとフロントエンド)、およびコーディング例を調べます。