ホームページ >バックエンド開発 >Python チュートリアル >高度な Python デコレータ: コードを強化する
あなたが賑やかなキッチンのシェフであると想像してみてください。レシピ、いわば機能があります。時間が経つにつれて、ほとんどの料理には、提供する前にオリーブオイル、塩ひとつまみ、またはハーブをふりかける必要があることがわかります。すべての料理にこれらの仕上げを手作業で加えるのではなく、自動的に仕上げてくれるアシスタントがいたら便利だと思いませんか? Python デコレータがコードに対して実行できるのはまさにこれであり、エレガントで再利用可能で表現力豊かな方法で機能を追加できます。
この記事では、高度な Python デコレータの世界を探っていきます。基本を超えて、パラメータ化されたデコレータ、スタック可能なデコレータ、さらにはクラスを備えたデコレータについても詳しく説明します。また、ベスト プラクティスと避けるべき落とし穴についても説明します。準備ができて?料理を始めましょう!
奥深くに入る前に、基礎を再確認しましょう。 Python のデコレータは、別の関数 (またはメソッド) を引数として受け取り、それを拡張して新しい関数を返す単純な関数です。以下に例を示します:
# Basic decorator example def simple_decorator(func): def wrapper(*args, **kwargs): print(f"Calling {func.__name__}...") result = func(*args, **kwargs) print(f"{func.__name__} finished.") return result return wrapper @simple_decorator def say_hello(): print("Hello, world!") say_hello()
出力:
Calling say_hello... Hello, world! say_hello finished.
さあ、高度な使用例を卒業しましょう。
場合によっては、デコレータは独自の引数を受け入れる必要があります。たとえば、さまざまなレベル (INFO、DEBUG、ERROR) でメッセージをログに記録するデコレータが必要な場合はどうなるでしょうか?
# Parameterized decorator example def log(level): def decorator(func): def wrapper(*args, **kwargs): print(f"[{level}] Calling {func.__name__}...") result = func(*args, **kwargs) print(f"[{level}] {func.__name__} finished.") return result return wrapper return decorator @log("INFO") def process_data(): print("Processing data...") process_data()
出力:
[INFO] Calling process_data... Processing data... [INFO] process_data finished.
この階層構造 (デコレーターを返す関数) は、柔軟なパラメーター化されたデコレーターを作成するための鍵となります。
Python では、複数のデコレータを 1 つの関数に適用できます。デコレータを 2 つ作成して積み重ねてみましょう。
# Stackable decorators def uppercase(func): def wrapper(*args, **kwargs): result = func(*args, **kwargs) return result.upper() return wrapper def exclaim(func): def wrapper(*args, **kwargs): result = func(*args, **kwargs) return result + "!!!" return wrapper @uppercase @exclaim def greet(): return "hello" print(greet())
出力:
HELLO!!!
ここでは、デコレータはボトムアップ方式で適用されます。@exclaim が挨拶をラップし、@uppercase が結果をラップします。
Python のあまり知られていない機能は、クラスをデコレータとして使用できることです。これは、状態を維持する必要がある場合に特に役立ちます。
# Class-based decorator class CountCalls: def __init__(self, func): self.func = func self.call_count = 0 def __call__(self, *args, **kwargs): self.call_count += 1 print(f"Call {self.call_count} to {self.func.__name__}") return self.func(*args, **kwargs) @CountCalls def say_hello(): print("Hello!") say_hello() say_hello()
出力:
Call 1 to say_hello Hello! Call 2 to say_hello Hello!
ここで、call メソッドにより、クラスが関数のように動作できるようになり、ターゲット関数をシームレスにラップできるようになります。
デコレータはクラス内のメソッドと同様に機能します。ただし、自分自身を正しく扱うことが不可欠です。
# Method decorator example def log_method(func): def wrapper(self, *args, **kwargs): print(f"Method {func.__name__} called on {self}") return func(self, *args, **kwargs) return wrapper class Greeter: @log_method def greet(self, name): print(f"Hello, {name}!") obj = Greeter() obj.greet("Alice")
出力:
Method greet called on <__main__.Greeter object at 0x...> Hello, Alice!
場合によっては、デコレータをリソース管理と統合する必要があります。たとえば、関数の実行時間を計測するデコレータを作成してみましょう。
import time # Timing decorator def time_it(func): def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) end = time.time() print(f"{func.__name__} took {end - start:.2f} seconds") return result return wrapper @time_it def slow_function(): time.sleep(2) print("Done sleeping!") slow_function()
出力:
# Basic decorator example def simple_decorator(func): def wrapper(*args, **kwargs): print(f"Calling {func.__name__}...") result = func(*args, **kwargs) print(f"{func.__name__} finished.") return result return wrapper @simple_decorator def say_hello(): print("Hello, world!") say_hello()
デコレーターと作業するときは、可読性と保守性を念頭に置くことが重要です。ここにいくつかのヒントがあります:
Calling say_hello... Hello, world! say_hello finished.
徹底的にテストする: デコレーターは、特に複数のデコレーターをチェーンする場合に、微妙なバグを引き起こす可能性があります。
ドキュメント デコレータ: 各デコレータの動作とその期待されるパラメータを明確に文書化します。
過度の使用を避ける: デコレーターは強力ですが、過度に使用するとコードを理解しにくくなる可能性があります。
デコレーターは、Python の最も表現力豊かな機能の 1 つです。これらを使用すると、クリーンで再利用可能な方法で動作を拡張および変更できます。パラメータ化されたデコレータからクラスベースの実装まで、可能性は無限です。スキルを磨くと、デコレーターを活用して、よりクリーンで Python 的なコードを作成できるようになります。そしておそらく、偉大なシェフのように、作成するすべてのレシピに独自のタッチを加えることができます。
注: AI 支援コンテンツ
以上が高度な Python デコレータ: コードを強化するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。