検索
ホームページバックエンド開発Python チュートリアルよりクリーンで効率的なコードのための重要な Python デコレータ パターン

ssential Python Decorator Patterns for Cleaner, More Efficient Code

ベストセラー作家として、アマゾンで私の本を探索することをお勧めします。 Medium で私をフォローしてサポートを示すことを忘れないでください。ありがとう!あなたのサポートは世界を意味します!

Python デコレータは、コア ロジックを変更せずに関数やクラスを変更または拡張できる強力な機能です。開発者として、デコレータ パターンをマスターすると、コードの品質、再利用性、保守性が大幅に向上することがわかりました。私のプロジェクトで特に便利だと感じた 7 つの重要なデコレータ パターンを見てみましょう。

クラスデコレーター

クラス デコレータは、クラスの動作と属性を変更または強化する方法を提供します。これらは、クラス定義のすぐ上の @decorator 構文を使用して適用されます。私は、メソッドの追加、既存のメソッドの変更、クラス属性の変更にクラス デコレータをよく使用してきました。

これは、クラスに新しいメソッドを追加するクラス デコレーターの例です。

def add_greeting(cls):
    def say_hello(self):
        return f"Hello, I'm {self.name}"
    cls.say_hello = say_hello
    return cls

@add_greeting
class Person:
    def __init__(self, name):
        self.name = name

person = Person("Alice")
print(person.say_hello())  # Output: Hello, I'm Alice

この例では、add_greeting デコレーターは、say_hello メソッドを Person クラスに追加します。このパターンは、ソース コードを変更せずに複数のクラスにわたって機能を拡張したい場合に特に便利です。

引数を持つ関数デコレータ

引数を受け入れる関数デコレータを使用すると、さらに柔軟性が高まります。これらを使用すると、デコレーター自体の動作をカスタマイズできます。さまざまなユースケースに合わせて微調整できる再利用可能なデコレータを作成する場合、このパターンが非常に貴重であることがわかりました。

これは、指定された回数だけ関数呼び出しを繰り返すことができるデコレータの例です:

def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(times=3)
def greet(name):
    print(f"Hello, {name}!")

greet("Bob")
# Output:
# Hello, Bob!
# Hello, Bob!
# Hello, Bob!

この例では、repeat デコレータは、装飾された関数を何回呼び出すかを決定する引数を受け取ります。このパターンにより、デコレータを関数に適用する方法に大きな柔軟性が与えられます。

関数メタデータの保存

デコレーターを使用する場合、元の関数のメタデータを保持することが重要です。これには、関数の名前、docstring、およびその他の属性が含まれます。 Python 標準ライブラリの functools.wraps デコレータは、これを実現するのに役立ちます。

これが例です:

from functools import wraps

def my_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        """This is the wrapper function"""
        print("Something is happening before the function is called.")
        result = func(*args, **kwargs)
        print("Something is happening after the function is called.")
        return result
    return wrapper

@my_decorator
def say_hello(name):
    """This function greets someone"""
    print(f"Hello, {name}!")

say_hello("Charlie")
print(say_hello.__name__)  # Output: say_hello
print(say_hello.__doc__)   # Output: This function greets someone

@wraps(func) を使用することで、ラッパー関数が元の関数のメタデータを確実に引き継ぐことができます。これはデバッグとイントロスペクションにとって非常に重要です。

複数のデコレータを積み重ねる

デコレータはスタックできるため、複数のデコレータを 1 つの関数に適用できます。装飾の順序は重要であり、デコレータは下から上に適用されます。

これが例です:

def decorator1(func):
    def wrapper(*args, **kwargs):
        print("Decorator 1")
        return func(*args, **kwargs)
    return wrapper

def decorator2(func):
    def wrapper(*args, **kwargs):
        print("Decorator 2")
        return func(*args, **kwargs)
    return wrapper

@decorator1
@decorator2
def greet(name):
    print(f"Hello, {name}!")

greet("David")
# Output:
# Decorator 1
# Decorator 2
# Hello, David!

この例では、decorator2 が最初に適用され、次にdecorator1 が適用されます。複数のデコレータを使用する場合、実行順序を理解することが重要です。

メモ化デコレーター

メモ化は、負荷の高い関数呼び出しの結果を保存し、同じ入力が再度発生したときにキャッシュされた結果を返す最適化手法です。メモ化デコレーターは、再帰関数や高価な計算を伴う関数のパフォーマンスを向上させるのに非常に便利であることがわかりました。

メモ化デコレータの例を次に示します:

def add_greeting(cls):
    def say_hello(self):
        return f"Hello, I'm {self.name}"
    cls.say_hello = say_hello
    return cls

@add_greeting
class Person:
    def __init__(self, name):
        self.name = name

person = Person("Alice")
print(person.say_hello())  # Output: Hello, I'm Alice

このメモ化デコレーターはフィボナッチ関数の結果をキャッシュし、大規模な入力に対するパフォーマンスを劇的に向上させます。

タイミングおよびロギングデコレーター

関数実行のタイミングと関数呼び出しのログを記録するためのデコレーターは、パフォーマンス分析とデバッグに非常に役立ちます。私は開発プロセスでこれらを頻繁に使用します。

これは、タイミングとロギングのデコレーターを組み合わせた例です。

def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(times=3)
def greet(name):
    print(f"Hello, {name}!")

greet("Bob")
# Output:
# Hello, Bob!
# Hello, Bob!
# Hello, Bob!

このデコレーターは、関数が呼び出されたときと実行にかかる時間をログに記録します。これは、コード内のパフォーマンスのボトルネックを特定するのに非常に貴重なパターンです。

コンテキストマネージャーデコレーター

コンテキスト マネージャーは通常、リソース管理とエラー処理のために with ステートメントとともに使用されます。関数をコンテキスト マネージャーに変えるデコレーターを作成して、エレガントなセットアップと破棄操作を可能にすることができます。

これが例です:

from functools import wraps

def my_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        """This is the wrapper function"""
        print("Something is happening before the function is called.")
        result = func(*args, **kwargs)
        print("Something is happening after the function is called.")
        return result
    return wrapper

@my_decorator
def say_hello(name):
    """This function greets someone"""
    print(f"Hello, {name}!")

say_hello("Charlie")
print(say_hello.__name__)  # Output: say_hello
print(say_hello.__doc__)   # Output: This function greets someone

この例では、file_manager デコレーターは、例外が発生した場合でも、操作後にファイルが適切に閉じられるようにします。

デコレータの作成と使用のベスト プラクティス

デコレーターと協力するときに、私に役立ついくつかのベスト プラクティスを学びました。

  1. 関数のメタデータを保存するには、functools.wraps を使用します。
  2. デコレータはシンプルにして、単一の責任に集中してください。
  3. デコレータに引数を渡す必要がある場合は、デコレータ ファクトリを使用します。
  4. 特に頻繁に呼び出される関数については、デコレータのパフォーマンスへの影響に注意してください。
  5. デコレータを明確に文書化し、デコレータの動作とその副作用を説明します。
  6. デバッグするときは、デコレーターが間接層を追加することに注意してください。 Python デバッガーの @ 構文などのツールは、装飾された関数にステップインするのに役立ちます。

装飾されたコードのテストは難しい場合があります。私がよく使用するアプローチの 1 つは、デコレーターを装飾された関数とは別にテストすることです。これにより、より詳細なテストが可能になり、デバッグが容易になります。

デコレーターをテストする方法の例を次に示します。

def decorator1(func):
    def wrapper(*args, **kwargs):
        print("Decorator 1")
        return func(*args, **kwargs)
    return wrapper

def decorator2(func):
    def wrapper(*args, **kwargs):
        print("Decorator 2")
        return func(*args, **kwargs)
    return wrapper

@decorator1
@decorator2
def greet(name):
    print(f"Hello, {name}!")

greet("David")
# Output:
# Decorator 1
# Decorator 2
# Hello, David!

このテストでは、モック関数を使用して、デコレータが元の関数を正しく呼び出し、その結果を返しているかどうかを確認します。

デコレーターは Python の強力なツールであり、これらのパターンをマスターすると、コーディングの武器を大幅に強化できます。これらにより、懸念事項の明確な分離が可能になり、コードの再利用が促進され、コードがより読みやすく保守しやすくなります。

デコレーターを効果的に使用するための鍵は、単純なものから始めて、必要に応じて徐々に複雑さを増していくことであることがわかりました。基本的な関数デコレータから始めて、クラス デコレータやデコレータ ファクトリなどのより高度なパターンに進みます。

デコレーターはコードを大幅に改善できますが、慎重に使用する必要があることに注意してください。デコレータを過度に使用すると、理解やデバッグが困難なコードになる可能性があります。デコレータが特定のユースケースにとって最適なソリューションであるかどうかを常に検討してください。

デコレーターとの作業を続けると、新しいパターンや使用例を発見する可能性があります。 Python コミュニティは常に革新を続けており、新しいデコレータ テクニックが定期的に登場します。好奇心を持ち、さまざまなアプローチを試し、プロジェクト固有の問題を解決するために独自のデコレーター パターンを遠慮なく作成してください。

デコレータは、よりクリーンで効率的なコードを作成するのに役立つ Python の多くの強力な機能の 1 つにすぎません。デコレーターに慣れてくると、デコレーターがジェネレーター、コンテキスト マネージャー、メタクラスなどの他の Python 機能とうまく統合され、エレガントで強力なコード設計の可能性がさらに広がることがわかります。


101冊

101 Books は、著者 Aarav Joshi が共同設立した AI 主導の出版社です。高度な AI テクノロジーを活用することで、出版コストを信じられないほど低く抑えており、書籍によっては $4 という低価格で販売されており、誰もが質の高い知識にアクセスできるようになっています。

Amazon で入手できる私たちの書籍 Golang Clean Code をチェックしてください。

最新情報とエキサイティングなニュースにご期待ください。本を購入する際は、Aarav Joshi を検索して、さらに多くのタイトルを見つけてください。提供されたリンクを使用して特別割引をお楽しみください!

私たちの作品

私たちの作品をぜひチェックしてください:

インベスターセントラル | 投資家中央スペイン人 | 中央ドイツの投資家 | スマートな暮らし | エポックとエコー | 不可解な謎 | ヒンドゥーヴァ | エリート開発者 | JS スクール


私たちは中程度です

Tech Koala Insights | エポックズ&エコーズワールド | インベスター・セントラル・メディア | 不可解な謎 中 | 科学とエポックミディアム | 現代ヒンドゥーヴァ

以上がよりクリーンで効率的なコードのための重要な Python デコレータ パターンの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
Python Switchステートメントとは何ですか?Python Switchステートメントとは何ですか?Apr 30, 2025 pm 02:08 PM

この記事では、バージョン3.10で導入されたPythonの新しい「マッチ」ステートメントについて説明します。これは、他の言語のスイッチステートメントに相当するものです。コードの読みやすさを向上させ、従来のif-elif-elよりもパフォーマンスの利点を提供します

Pythonの例外グループとは何ですか?Pythonの例外グループとは何ですか?Apr 30, 2025 pm 02:07 PM

Python 3.11の例外グループは、複数の例外を同時に処理することで、同時シナリオと複雑な操作でエラー管理を改善します。

Pythonの関数注釈とは何ですか?Pythonの関数注釈とは何ですか?Apr 30, 2025 pm 02:06 PM

Pythonの関数注釈は、タイプチェック、ドキュメント、およびIDEサポートの関数にメタデータを追加します。それらはコードの読みやすさ、メンテナンスを強化し、API開発、データサイエンス、ライブラリの作成において重要です。

Pythonのユニットテストとは何ですか?Pythonのユニットテストとは何ですか?Apr 30, 2025 pm 02:05 PM

この記事では、Pythonの単体テスト、その利点、およびそれらを効果的に書く方法について説明します。テスト用のUnittestやPytestなどのツールを強調しています。

Pythonのアクセス仕様とは何ですか?Pythonのアクセス仕様とは何ですか?Apr 30, 2025 pm 02:03 PM

記事では、Pythonのアクセス仕様について説明します。Pythonは、厳格な執行ではなく、クラスメンバーの可視性を示すために命名規則を使用します。

Pythonの__init __()とは何ですか?また、セルフはどのように役割を果たしますか?Pythonの__init __()とは何ですか?また、セルフはどのように役割を果たしますか?Apr 30, 2025 pm 02:02 PM

記事では、Pythonの\ _ \ _ init \ _ \ _()メソッドと、オブジェクト属性の初期化における自己の役割について説明します。 \ _ \ _ init \ _ \ _()に対するその他のクラス方法と継承の影響についてもカバーされています。

Pythonの@ClassMethod、@StaticMethod、およびインスタンスメソッドの違いは何ですか?Pythonの@ClassMethod、@StaticMethod、およびインスタンスメソッドの違いは何ですか?Apr 30, 2025 pm 02:01 PM

この記事では、@ClassMethod、@StaticMethod、およびPythonのインスタンスメソッドの違いについて説明し、そのプロパティ、ユースケース、および利点を詳述します。必要な機能とDAに基づいて適切な方法タイプを選択する方法を説明します

Pythonアレイに要素をどのように追加しますか?Pythonアレイに要素をどのように追加しますか?Apr 30, 2025 am 12:19 AM

inpython、youappendelementStoalistusingtheappend()method.1)useappend()forsingleelements:my_list.append(4).2)useextend()or = formultipleElements:my_list.extend(another_list)ormy_list = [4,5,6] .3)forspecificpositions:my_list.insert(1,5).beaware

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター