How to understand the calling sequence of Python decorator -
i confused calling sequence of following code piece.
#/usr/bin/python def decorator_no_args(fn): if not callable(fn): raise typeerror def wrapper(): return fn() print "decorator_no_args" return wrapper @decorator_no_args def foo_no_args(): print "foo_no_args" def decorator_args(* args, **kargs): def wrapper0(fn): def wrapper1(*args, **kargs): return fn(*args, **kargs) return wrapper1 print "decorator_args" return wrapper0 @decorator_args(1) def foo_args(arg0): print "foo_args" if __name__ == "__main__": foo_no_args()
the output is:
decorator_no_args decorator_args foo_no_args
function decorator_args()
isn't called can see above. why recorded?
2 things: decorators applied when function definition executed, , @expression
syntax takes expression; evaluated when decorating.
the line @decorator_args(1)
calls decorator_args()
function, passing in 1
argument. result of call used decorator.
decorators syntactic sugar, this:
@decorator_args(1) def foo_args(arg0): print "foo_args"
is executed as:
def foo_args(arg0): print "foo_args" foo_args = decorator_args(1)(foo_args)
note decorator_args(1)
is called. , it's return value called again, produce decorated result.
when @ decorator_args()
see returns decorator:
def decorator_args(* args, **kargs): def wrapper0(fn): def wrapper1(*args, **kargs): return fn(*args, **kargs) return wrapper1 print "decorator_args" return wrapper0
wrapper0
real decorator; returned when decorator_args()
called. foo_args()
passed wrapper0()
(as fn
argument), , original function replaced wrapper1
.
it doesn't matter @ foo_args
never called; decorators not applied each time when call function, applied once. if called foo_no_args()
more once, decorator_no_args
message not repeated.
Comments
Post a Comment