The concept of Python's decorator has been a bit tricky. I have seen a very clear description of the feeling in StackOverflow before:
*a Decorator must accept A function as an argument reference address: http://stackoverflow.com/questions/739654/ how-can-i-make-a-chain-of-function-decorators-in-python/1594484#1594484http://stackoverflow.com/questions/ 13857/can-you-explain-closures-as-they-relate-to-python Objects is data with methods attached, closures is functions With data attached. The English proficiency is limited, for this sentence my understanding has been this way:
1 defA (FN):2 Print "function A"3 defTmpfun (*args):4 Print "Tmpfunc"5Fu (*args)6 returnTmpfun7 8 @a9 defB (*args):Ten Print "function B"+ str (args)
At this point, invoking B (1, 2) is equivalent to a (b (1, 2)), and when the compiler parses the code, it executes B and then executes a. Today, when someone asks a similar question, try to write it and find that the equivalent method is running in error. The experiment shows that B (1, 2) is equivalent to a (b) (1, 2) when a B function call is decorated with an adorner.
the parameters required by the adorner function should be the modified function object, not the execution result of the modified function object. The following is the validation code:
1 defAddspan (FN):2 Print "Addspan executed"3 defN (*args):4 Print "spam, spam, spam"5 returnFN (*args)6 returnN7 8 @addSpan9 defuseful (A, B):Ten PrintA**2 + b**2 One A defsynonym (A, b): - PrintA**2 + b**2 - the if __name__=='__main__': -Useful (3, 4) -Addspan (synonym) (3, 4)
The result of the execution is:
Addspan executedspam, spam, spamaddspan executedspam, spam, spam 0.1s]
It can be seen that although formally decorated functions are executed first, the actual execution is still performed with the adorner function as the entry.
Reflection:
Functions that act as adorners must receive parameters and must return an executable function object, otherwise an error occurs:
def A (): Print " function A " @a def b (): Print " function B " B ()
Operation Result:
Traceback (most recent): " /users/.../decorator_test1.py " in <module> @aTypeError: A () takes no arguments (1 in 0.1s with exit code 1]
An error also occurs if the adorner function declares a parameter but does not declare a return object, or if the declared return object is an object that is not callable:
def A (FN): Print " function A " no declaration returned object @adef B (): print"function B" B ()
Execution Result:
Traceback (most recent): " /users/.../decorator_test1.py " in <module>function a 'nonetype'are not in 0.1s with exit code 1]
You can see that subsequent actions continue with none as the returned object, and then an error occurs.
Or:
def A (FN): Print " function A " return " ASD " declares that the returned object is a non-callable type @adef B ( ):print"function B "B ()
Operation Result:
function Atraceback (most recent call last): " /users/.../decorator_test1.py " in <module> 'str ' are not in 0.1s with exit code 1]
Normal operation Result:
def A (FN): Print " function A " return fn // return parameter derived function object @adef B (): print" function B"B ()
Operation Result:
in 0.1s]
There are some questions about adorners that will be verified in the second article.
About Python decorators (1)