Python装飾器漫談

1596 ワード

参考資料http://python.jobbole.com/81683/
  • Pythonのネーミングスペースのいずれかの変数は、作成時に自分のネーミングスペースに作成されます.自分のネーミングスペースにこの名前が含まれていない場合は、上層のネーミングスペースを上書きするのではなく、新しいネーミングスペースが作成されます.アクセス時に、自分のネーミングスペースにない場合は、上層にアクセスします.
  • Pythonの閉パッケージのどの関数もオブジェクトです.呼び出すオブジェクトを作成できます.呼び出される関数を作成すると、内部プロシージャでローカル変数が使用され、閉パッケージが設計されます.ネストされた非グローバルな役割ドメインに定義された関数は、定義されたときに閉じたネーミングスペースを記憶することができます.

  • 一般的には、サブ関数は親関数のローカル変数を使用することができ、この動作を閉パッケージと呼びます.
  • 閉パッケージ詳細のC++とPythonの一般的な場合、ほとんどの言語の親関数のローカル変数は、親関数が終了するにつれてライフサイクルを終了します.このときlambda関数、または関数オブジェクトの呼び出しで、親関数のローカル変数を参照すると問題が発生します.lambdaまたは関数オブジェクトを定義して定義するときに、現在のネーミングスペースを記憶できるのは閉パッケージです.しかしC++では、局所変数のライフサイクル規定は親関数と同じですが、どうすればいいですか?mutableを使用して変数を修飾すると、変数のライフサイクルが関数オブジェクトやlambda式と同じ長さになります.そうしないと、これらの変数をスナップするときに問題が発生する可能性があります.Pythonは、閉じたオブジェクトを解放しないようにスナップします.関数オブジェクトが回収されるまで.
  • 装飾器は、関数を改装する必要がある場合がありますが、これらの改装作業はほとんど似ています.たとえば、関数の実行時間を計算する必要があります.この場合、すべての関数の開始と終了にタイムスタンプを付ける必要があります.その後、関数の終了時に印刷を行います.あるいは、パラメータと戻り値を検証する必要があります.もちろん、すべての関数の開始と終了時に検証関数を呼び出すことができます.

  • 装飾器はこのような機能を果たすことができます.たとえば関数があります
    def func():
        time.sleep(1)
    

    閉じたパッケージを持つ関数オブジェクトを返す別の関数を使用して、このような機能を完了します.
    def addTimePrint(func):
        def retFuncObj(*args, **kwargs):
            starttime = time()
            func(*args, **kwargs)
            print(time() - starttime)
        return retFuncObj
    

    新しいfunc関数を置き換える必要があります
    func = addTimePrint(func)
    

    Pythonは文法糖を提供し、addTimePrintを定義した後、@addTimePrintを使用して関数の定義と装飾を完了することができます.
    @addTimePrint
    def func():
        time.sleep(1)