web-dev-qa-db-ja.com

デコレートされた関数が完了した後にPythonデコレータを実行するにはどうすればよいですか?

デコレータを使用してさまざまな関数の監査を処理したい(主にDjango関数を表示しますが、排他的ではありません)。これを行うために、関数を監査できるようにしたい実行後-つまり、関数は通常どおり実行され、例外なく返される場合、デコレータはファクトをログに記録します。

何かのようなもの:

@audit_action(action='did something')
def do_something(*args, **kwargs):
    if args[0] == 'foo':
        return 'bar'
    else:
        return 'baz'

どこ audit_actionは、関数が完了した後にのみ実行されます。

30

デコレータは通常、ラッパー関数を返します。ラップされた関数を呼び出した後、ロジックをラッパー関数に入れるだけです。

_def audit_action(action):
    def decorator_func(func):
        def wrapper_func(*args, **kwargs):
            # Invoke the wrapped function first
            retval = func(*args, **kwargs)
            # Now do something here with retval and/or action
            print('In wrapper_func, handling action {!r} after wrapped function returned {!r}'.format(action, retval))
            return retval
        return wrapper_func
    return decorator_func
_

したがって、audit_action(action='did something')は、スコープ付きの_decorator_func_を返すデコレータファクトリであり、_do_something_(do_something = decorator_func(do_something))を装飾するために使用されます。

装飾後、_do_something_参照は_wrapper_func_に置き換えられました。 wrapper_func()を呼び出すと、元のdo_something()が呼び出され、ラッパーfunc内のコードで処理を実行できます。

上記のコードをサンプル関数と組み合わせると、次の出力が得られます。

_>>> do_something('foo')
In wrapper_func, handling action 'did something' after wrapped function returned 'bar'
'bar'
_
37
Martijn Pieters

デコレータは、ここでそれ自体を処理できます。

def audit_action(function_to_decorate):
    def wrapper(*args, **kw):
        # Calling your function
        output = function_to_decorate(*args, **kw)
        # Below this line you can do post processing
        print "In Post Processing...."
        return output
    return wrapper
4
avasal