Vernacular to explain to you what the Python closures are?

Python is a closure concept is not one that can understand, but as you go in-depth study, in any case you will need to know such a thing.

The concept of closure

We try to go from concept to understand about the closure.

In some languages, the function may be (nested) defining another function, if the function of internal variables referenced external function, the closure may be generated. Closures may be used to create an association relationship between a function and a set of "private" variable. In the course of a given function is called multiple times, these private variables to maintain their persistence. -- Wikipedia

With relatively easy to understand people saying that when a function is treated as an object returned, entrainment of external variables, to form a closure. Look at an example.


def make_printer(msg):
    def printer():
        print msg  # 夹带私货(外部变量)
    return printer  # 返回的是函数,带私货的函数
printer = make_printer('Foo!')
printer()

Support will function as objects using programming languages ​​generally support closures. Such as Python, JavaScript.

How to understand closures

Closures there is what is it? Why do we need closure?

I personally believe that there is closure package significance is that it entrainment of external variables (contraband), entrainment of smuggled goods if it does not, its normal function and makes no difference. Function with a different entrainment of smuggled goods, on the realization of different functions. In fact, you can understand, the concept of closures and interface-oriented programming is like, the closure can be understood as a lightweight interface package.

Interface defines the constraints set of rules for the method signature.

def tag(tag_name):
    def add_tag(content):
        return "<{0}>{1}</{0}>".format(tag_name, content)
    return add_tag
    
content = 'Hello'

add_tag = tag('a')
print add_tag(content)
# <a>Hello</a>

add_tag = tag('b')
print add_tag(content)
# <b>Hello</b>

In this example, we want to add a content tag to function, but the specific tag_name what it was like to be determined according to actual needs, interfaces for external calls have been identified, it is add_tag ​​(content). If the interface-oriented manner in accordance with, we will first add_tag ​​written interfaces, specify the parameters and return types, respectively, and to realize a and b add_tag.

But the concept of closure in, add_tag ​​is a function that requires two parameters tag_name and content, but tag_name of this parameter is packed away. So at the outset can tell me how to pack, then take on the line.

The above example is not very vivid, in fact, we live and work, the concept of closures are also common. For example, phone dialer, you only care about the phone and call anyone, and not to tangle each brand of phone is how to achieve, which uses the module. Another example go to a restaurant, you can enjoy as long as the pay service, you do not know how much that table with food waste oil. These can be seen as a closure, is to return to some of the features or services (phone calls, meals), but these functions using external variables (antenna, cooking oil, etc.).

You can also be seen as a class instance of closure, when you are in the class structure, the use of different parameters, which is the closure of the bag package, class method is provided externally of closures. However, far greater than the class closure because only a closure function can be performed, but it is possible to provide a class instance many ways. Do not understand the learning process can join my python zero-based systems Learning Exchange Qiuqiu qun: 784758,214, current sharing Python enterprise talent needs and how Python from the zero-based learning with you, and learn what content. Related video learning materials, development tools have to share

When to use closures

In fact, closures are common in Python, but you did not pay particular attention to this is a closure. Such decorator Decorator Python in, if you need to write a parameterized decorator, then usually generate closures.

why? Since Python decoration is a fixed function interface. It requires your decorator function (decorator or the like) must return such an interface that accepts a function and returns a function:


# how to define
def wrapper(func1):  # 必须接受一个且仅一个函数作为参数
    return func2  # 返回一个且仅一个callable对象,一般为函数

# how to use
def target_func(args): # 目标函数
    pass

# 调用方式一,直接包裹
result = wrapper(target_func)(args)

# 调用方式二,使用@语法,等同于方式一
@wrapper
def target_func(args):
    pass

result = target_func()

So if your decorator if the arguments it? Then you need to pack a layer in the original decoration for receiving these parameters. These parameters (contraband) is transmitted to the inner layer of the decorator, the closure is formed. So when you need a decorator custom parameters, usually to form a closure. (Exception class decorator)


def html_tags(tag_name):
    def wrapper_(func):
        def wrapper(*args, **kwargs):
            content = func(*args, **kwargs)
            return "<{tag}>{content}</{tag}>".format(tag=tag_name, content=content)
        return wrapper
    return wrapper_

@html_tags('b')
def hello(name='Toby'):
    return 'Hello {}!'.format(name)

# 不用@的写法如下
# hello = html_tag('b')(hello)
# html_tag('b') 是一个闭包,它接受一个函数,并返回一个函数

print hello()  # <b>Hello Toby!</b>
print hello('world')  # <b>Hello world!</b>

Little deeper

In fact, do not be too deep, to understand this concept above, a lot of headaches code looks much better than this.

Let's take a look at the closure of the package in the end look like. In fact, the closure function relatively common and will be more of a function __closure__ attribute, which defines a tuple of objects used to store all the cell, each cell stores all eleven objects of the external variables closure.


>>> def make_printer(msg1, msg2):
    def printer():
        print msg1, msg2
    return printer
>>> printer = make_printer('Foo', 'Bar')  # 形成闭包

>>> printer.__closure__   # 返回cell元组
(<cell at 0x03A10930: str object at 0x039DA218>, <cell at 0x03A10910: str object at 0x039DA488>)

>>> printer.__closure__[0].cell_contents  # 第一个外部变量
'Foo'
>>> printer.__closure__[1].cell_contents  # 第二个外部变量
'Bar'

The principle is simple.

Guess you like

Origin blog.csdn.net/kkk123789/article/details/92188163