「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > Python デコレータの理解: ディープダイブ

Python デコレータの理解: ディープダイブ

2024 年 11 月 8 日に公開
ブラウズ:758

Python デコレータは、関数やメソッドの動作を変更または強化できる強力なツールです。一般的な使用例には、ロギング、認可などが含まれます。
ただし、デコレータを定義するように求められると、多くの人は

と言うかもしれません。

これは関数のラッパーです。

これは技術的には正しいですが、内部ではさらに多くのことが起こっています。

シンプルなデコレータの分析
簡単な例を見てみましょう:

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("Before calling the function")
        result = func(*args, **kwargs)
        print("After calling the function")
        return result
    return wrapper

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

ここで、my_decorator は関数say_hello のデコレータです。 Say_hello が定義されると、自動的に my_decorator に渡され、関数呼び出しが次のように変換されます:
Say_hello = my_decorator(say_hello)

この変化はいつ起こりますか?
この変換はコードのコンパイル中、特に実行時ではなく関数定義時に発生します。

コードの逆アセンブル
デコレータが下位レベルでどのように動作するかを理解するには、dis モジュールを使用してデコレータ関数のバイトコードを調べることができます:

import dis

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

dis.dis(say_hello)

バイトコードの内訳

dis.dis(say_hello) の出力は次のようになります:

Understanding Python Decorators: A Deep Dive
バイトコードの説明

  1. 関数を呼び出す前に

    • LOAD_GLOBAL: 印刷関数をロードします。
    • LOAD_CONST: '関数を呼び出す前に' メッセージをロードします。
    • CALL_FUNCTION: 通話を印刷します。
    • POP_TOP: 戻り値を破棄します。
  2. 元の関数の呼び出し

    • LOAD_DEREF: クロージャによってキャプチャされた元の関数 (func) をロードします。
    • LOAD_FAST: 位置引数とキーワード引数をロードします。
    • BUILD_MAP: キーワード引数の新しい辞書を作成します。
    • CALL_FUNCTION_EX: 引数を指定して元の関数を呼び出します。
    • STORE_FAST: 結果をローカル変数に保存します。
  3. 関数呼び出し後

    • 最初の部分と同様に、print を呼び出して「関数呼び出し後」を出力します。
    • 結果を返す
    • 結果変数をロードして返します。

結論
Python デコレーターは単なる関数ラッパーではありません。これらにより、定義時に関数の動作を変更できるようになります。デコレータがどのように機能するかを理解し、バイトコードを調べることで、プロジェクトでデコレータをより効果的に使用できるようになります。

今回はここまでです!他に詳しく知りたいことがあれば、ぜひお知らせください。

リリースステートメント この記事は次の場所に転載されています: https://dev.to/aman-iri/ Understanding-python-decorators-a-deep-dive-pp0?1 侵害がある場合は、[email protected] に連絡して削除してください。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3