pythonの中の装飾器の深さの剖析!

1831 ワード

カスタム修飾子パラメータなしの装飾:
@decorator
def func():
    pass

上記のコードは、次の実装に等しい.
fun = decorator(fun)

パラメータ付きの装飾:
@decorator('Amrzs')
def func():
     pass

このコードは、次の実装に等しい.
fun = decorator('Amrzs')(func)

しかし、この操作は装飾器を実現するたびにこのように実現するのは面倒なので、python内蔵の@文法はこれらの機能を実現してくれた.
また、decoratorによって装飾された関数は、それらの__name__が元のnowから装飾器の関数署名に変わったため、元の関数の__name__などの属性をwrapper()関数にコピーする必要がある.そうしないと、関数署名に依存するコードの実行がエラーになることがある.
つまりwrapper.__name__ = func.__name__というコードを書く必要があるが、Pythonに内蔵されたfunctools.wraps関数はすでに私たちにこのことを手伝ってくれた.したがって、decoratorの完全な書き方は以下の通りです.
import functools
def log(func):
    @functools.wraps(func) 
    def wrapper(*args, **kw): 
        print('call %s():' % func.__name__) 
        return func(*args, **kw)
return wrapper

あるいはパラメータ付き:
import functools
def log(text): 
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
             print('%s %s():' % (text, func.__name__))
             return func(*args, **kw) 
    return wrapper
return decorator

上記の知識に基づいて、この装飾器の@の原理に基づいて、私たちが今@permission_required(permission)のような装飾器を持っているようなより特定の機能を持つ装飾器を実現することは容易である.このデコレーションの機能は、permissionのパラメータに従って、対応する権限の動作を実行することである.管理者のみが操作できる装飾品を実現します.
def admin_required(func):
    return permission_required(Permission.ADMINISTER)(func)

原理は簡単で、実はpermission_required()関数のパラメータの値を内定して、デフォルトは管理者の権限で、またこの構造はpythonの@文法糖に合っているので、直接@admin_requiredのような方法でこの装飾器を使うことができます!
ははは!