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

Popular posts from this blog

android - Get AccessToken using signpost OAuth without opening a browser (Two legged Oauth) -

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: mockito -

google shop client API returns 400 bad request error while adding an item -