pythonステップ4.2---装飾器

2494 ワード


デコレーション
pythonはすべてオブジェクトであり、関数にとってもオブジェクトであり、関数オブジェクトは変数に割り当てることができるので、変数によって関数を呼び出すこともできます.
def test():
print("welcome to beijing")
test()
関数オブジェクトにはnameプロパティがあり、関数の名前を取得できます.
test.__name__
>>test
関数test()関数の機能を強化する場合は、たとえば、関数の前後にログを自動的に印刷しますが、test()関数の定義を変更したくない場合は、コードの実行中に機能を動的に追加する方法を「デコレータ(Decorator)」と呼びます.
def log(func):
def wrapper(*args,**kw):
    print("where are you from?")
    return func(*args,**kw)
return wrapper
@log
#      ,       
def test():
    print("welcome to beijing")
test()
上のlogを観察すると、彼は装飾器(decorator)なので、パラメータとして関数を受け入れ、関数を返します.Python@構文を使用して、decoratorを関数定義に配置します.
@log
def test():
    print("welcome to beijing")
test()
test関数を呼び出すと、関数自体だけでなく、デザイナの内容を実行してtest()関数の定義に@logを置き、文を実行することに相当します.
test=log(test)
log()はdecoratorであり、関数を返すため、元のtest()関数は依然として存在しますが、現在同じ名前のtest変数が新しい関数を指しているだけで、test()を呼び出すと新しい関数、すなわちlog()関数で返されるwrapper()関数の数が実行されます.wrapper()関数のパラメータの定義は(args,*kw)であるため、wrapper()関数は任意のパラメータの呼び出しを受け入れることができる.wrapper()関数では、まずログを印刷し、元の関数を呼び出します.decorator自体がパラメータを入力する必要がある場合は、decoratorを返す高次関数を記述する必要があります.書くのは複雑です.
ページ関数の前後にログイン検証や印刷情報を追加するなど、関数の前後に対応する機能を追加する必要がある場合は、次のような3つのネストが必要です.
def Before(request,kargs):
    print ('before')
def After(request,kargs):
    print ('after')
def Filter(before_func,after_func):
    def outer(main_func):
        def wrapper(request,kargs):
            before_result = before_func(request,kargs)
            if(before_result != None):
                return before_result;
            main_result = main_func(request,kargs)
            if(main_result != None):
                return main_result;
            after_result = after_func(request,kargs)
            if(after_result != None):
                return after_result;

        return wrapper
    return outer

@Filter(Before, After)
def Index(request,kargs):
    print ('index')
Index('a','b')
まず、3層コードの実行過程について説明します.原理は2層と同じです.1.Before、After、Filter関数を順にメモリにロードする.装飾器3をロードする.Filter()関数を実行し、outer()関数をロードし、returnのouter()関数を返し、wrapper()関数をロードし、returnのwrapper()関数を返します.Index()関数を実行し、パラメータ5に入力し、wrapper()関数を実行します.