1, Closure (closure)
Closures are a feature supported by Python that allows functions defined in non-global scope to reference variables in its outer space, which are referred to as environment variables of this function. The environment variable, together with this non global function, forms the closure.
The code is as follows |
Copy Code |
def outer (x): y = [1,2,3] def inner (): Print X Print Y return inner x = 5 #这个x没有被引用 f = Outer (2) F () |
Print f.__closure__ #函数属性__closure__存储了函数的环境变量 def entrance (func):
= 5 #这个x没有被引用f = outer (2) f () print f.__closure__ #函数属性__closure__存储了函数的环境变量 def entrance (func):
Both X and Y are part of the function outer namespace, referenced in inner, and when the outer function exits, the outer namespace does not exist, but inner maintains its connection to its external variable x,y when it is defined.
Program output:
2
[1, 2, 3]
(, )
The adorner is a callable object (a callable), in Python, the function is an object, and of course it is callable, so the adorner can be a function, which we call the function adorner.
This callable object takes a function as a parameter, closes and returns another function (to replace the parameter that function).
Like what:
The code is as follows |
Copy Code |
def entrance (func): def inner (): Print "Inside function:", func.__name__ Func () return inner |
Entrance is an adorner, which is a function that can receive a function func as a parameter and return another function inner.
So why is it called an adorner, which calls the Func () inside the return function inner (), and also makes an extra operation, equivalent to "decorate" the function func.
How to use the adorner?
The code is as follows |
Copy Code |
Def fun1 (): Pass FUN1 = entrance (FUN1) Def fun2 (): Pass fun2 = entrance (fun2) |
FUN1,FUN2 's name has not changed, but by invoking the function adorner entrance (), they have pointed to another function inner (), "decorated" themselves.
@ operator Www.111cn.net
The @ symbol provided by Python is essentially the above, and the new assignment of a function name is a grammatical technique. So the code above is equivalent to
The code is as follows |
Copy Code |
@entrance Def fun1 (): Pass @entrance Def fun2 (): Pass |
What is the use of the adorner?
From this deliberately constructed very simple example, you can see the meaning of the adorner, if a function requires a function, if the function can be used on many functions, or the function is not the implementation of their own, then you can write an adorner to implement these functions.
The above adorner entrance, after decorating a function, the function is called to print out the name of the function.
But there is a problem with this adorner, functionally, that it should be used to decorate any function, but if we use it to decorate a function with parameters
The code is as follows |
Copy Code |
@entrance def fun3 (x): Pass |
As long as FUN3 is not invoked, these three lines of code do not give the Python interpreter an error, as we already know it is equivalent to:
The code is as follows |
Copy Code |
def fun3 (x): Pass FUN3 = entrance (FUN3) |
We define a function fun3 with a parameter, and then point the FUN3 to another function inner (), of course there is nothing wrong with it.
However, when we use FUN3, we will definitely use it as it is defined, passing it a parameter.
>>>FUN3 (1)
There's going to be a mistake, see how the interpreter complains.
The code is as follows |
Copy Code |
Traceback (most recent call last): File "decorator.py", line, in Www.111cN.net <module> FUN3 (1) Typeerror:inner () takes no arguments (1 given) |
Of course, we can easily know why this error, FUN3 has not pointed to its definition of the function, it now points to "inner ()", and inner is not parameters, of course, error.
So how do we solve it?
Modify the definition of inner () so that it can take any argument on it. "Note: See Python function text"
The code is as follows |
Copy Code |
def entrance (func): 2 def inner (*args, **kvargs): Print "Inside function:", func.__name__ Func (*args, **kvargs) return inner |
Now, there is no error in passing any of the arguments to inner, that is, entrance can be used to decorate any function.
3, write an adorner logger
When a function is invoked, it records its name and the actual parameters being invoked in the log
code is as follows |
copy code |
def logger ( Func): def inner (*args, **kvargs): print func.__name__, ' called, arguments: ', args, Kvargs func (*args, **kvargs return inner |