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