Closures and decorators in 21.python

Source: Internet
Author: User

Closures in Python are defined (interpreted) as: if, in an intrinsic function, a reference is made to a variable in an outer scope (but not at the global scope), the intrinsic function is considered a closure (closure).

  The following instructions are primarily for python2.7, and other versions may differ.

Perhaps the definition is not very clear, let's take a look at what is called an intrinsic function:

def Wai_hanshu (canshu_1):     def Nei_hanshu (canshu_2):  #  I have defined a function inside the function        return canshu_1*Canshu _2    return nei_hanshu   #  I'm going to return the inner function  = Wai_hanshu (123)     #  at this time canshu_1 = 123print  aprint A (321)    # canshu_2 = 321

I have nested a function inside the function, and when I pass a variable to the outer function and assign it to a, we find that a becomes a function object, and when I pass the argument to the function object again, I get the return value of the intrinsic function. We know that, by the principle of scope, we cannot access the local scope at the global scope. However, the intrinsic function is accessed through the flattering method:

Let's continue to look at an example:

def Wai_hanshu ():     = []    def  Nei_hanshu (Canshu):        a.append (Canshu)        return  a     return= Wai_hanshu ()print A (123)print A ( 321)

You can see that the list a function in the outer function has changed. To understand why, you need to know what a Python namespace is, and the namespace is the cause of the scope performance, here's a brief description.

The main reason for introducing namespaces is to avoid variable collisions, because there are many modules in Python, functions in modules, classes, and so on, all of which are used in variables. But if you pay attention every time not to conflict with other variable names, it is too much trouble, developers should focus on their own problems, rather than consider what other people write the application of the variables, so Python introduced the namespace. Namespaces are divided into modules, which are divided into global scopes and local scopes, which are represented by a graph:

There are different namespaces between modules, and there are global and local scopes, which can be nested before local scopes, so that variable names do not conflict. Here, by the way, you can get the name of the namespace by using the __name__ property:

The namespace of the primary file is called ' __main__ ', and the module's namespace is the module name.

The scope was born because when Python was looking for a variable, it would first look in the current namespace, if not in the current namespace, go to the previous level of the namespace, and so on, if not found at the end, the trigger variable did not find the exception.

We've been saying that global scopes cannot access local scopes, and local scopes can access the global scope for this reason. And when I create a variable with the same name in the local scope, Python finds it first in the current scope when looking for the variable, and does not continue looking up the top level.

In earlier versions of Python, local scopes were inaccessible to other local scopes, only the global, and now the versions were looked up in turn, and here's a mention.

That is, because of this feature, we can access the variables in the external function in the inner function, which is called closure.

Note: This is a good place to distinguish between objects, such as:

def Wai_hanshu ():     = []    def  Nei_hanshu (Canshu):        a.append (Canshu)        return  a     return= Wai_hanshu ()    #  I created an object B = Wai_hanshu ()    #  I created another object. print  aprint  bprint A (123)  print B (321)

Here, although we are all operating Wai_hanshu variables, but A and B is completely two objects, they are located in the memory space is also different, so the data is also independent. Be careful not to confuse.

Decorative Device

  In fact, the decorator is on the basis of the closure of a few more steps to see the code:

defZSQ (func):#Decorative Functions    defnei ():Print 'I do some things before the incoming function executes.'func ()#Execute function        Print 'I'll do something after the target function executes.'    returnneidefLogin ():#be decorated function    Print 'I have a login function'Login= ZSQ (login)#I'm going to pass the decorated function into the adornment function and overwrite the entry of the original function .Login ()#This is where the decorated function is executed.

Here are a few things to know when looking at this code:

1. The parameters of the function are passed in fact as references, not values.

2. The function name is also a variable, so you can re-assign the value.

3. When assigning operations, first execute the right side of the equals sign.

Only by understanding the above, and then combining the code, you should be able to understand what an adorner is. The so-called adorner is on the basis of the closure of the transfer of a function, and then overwrite the original function of the execution of the portal, later call this function, you can implement some additional functions. The existence of adorners is mainly to not modify the original function of the code, and do not modify other calls to this function code, you can achieve the expansion of the function.

And Python feels it's too inconvenient to make a rename every time, so it's a handy way to write:

defzsq (func):defnei ():Print 'I do some things before the incoming function executes.'func ()#Execute function        Print 'I'll do something after the target function executes.'    returnnei@zsq#The function below is automatically passed as a parameter to the decoration function .deflogin ():Print 'I have a login function'Login ()

  

These little conveniences are also called Python's syntactic sugars, and you may have seen this in many places.

Adorner with parameters:

defzsq (a):Print 'I'm the decorator's parameter.', adefnei (func):Print 'I do some things before the incoming function executes.'func ()#Execute function        Print 'I'll do something after the target function executes.'    returnnei@zsq ('123')deflogin ():Print 'I have a login function'

Equivalent: login = ZSQ (123) , so there is no call here to execute.

Nesting of adorners:

Here is not a complete example:

def func ():      Pass

Equivalent: func = Deco1 (Deco_arg) (Deco2 (func))

That is, nesting from top to bottom.

About closures and decorators first here, there is a need to add later.

Closures and decorators in 21.python

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.