A simple example of the Python adorner decorator

Source: Internet
Author: User
Tags closure in python

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

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.