Closures in Python are not a concept that you can understand. but as you go deeper, you need to understand such a thing in any way. Closures in Python are not a concept that you can understand. but as you go deeper, you need to understand such a thing in any way. 
 
Closure concept
 
We try to understand the closure from the concept.
 
In some languages, when a function can (nested) define another function, a closure may be generated if the internal function references the variable of an external function. Closures can be used to create associations between a function and a group of "private" variables. When a given function is called multiple times, these private variables can maintain its persistence.
 
-- Wikipedia)
 
It is easy to understand that when a function is returned as an object, an external variable is included to form a closure. Let's look at the example.
 
Def make_printer (msg): def printer (): print msg # return printer with private goods (external variable) # returns a function. the printer with private goods = make_printer ('foo! ') Printer () 
Functions can be used as programming languages for objects. closures are generally supported. For example, Python and JavaScript.
 
How to understand closures
 
What is the significance of the existence of closures? Why is closure required?
 
In my opinion, a closure has an external variable (private goods). if it does not include private goods, it is no different from a common function. Different functions are implemented when the same function carries different private goods. In fact, you can also understand that closures are similar to interface-oriented programming. they can be understood as lightweight interface encapsulation.
 
The interface defines a set of constraints on the method signature.
 
def tag(tag_name):     def add_tag(content):         return "<{0}>{1}
 ".format(tag_name, content)     return add_tag  content = 'Hello'  add_tag = tag('a') print add_tag(content) # Hello  add_tag = tag('b') print add_tag(content) # Hello 
In this example, we want to add a tag to the content, but the specific tag_name is determined based on actual requirements, and the interface called by the external interface has been determined, is add_tag (content ). If the implementation is based on the interface-oriented approach, we first write add_tag as an interface, specify its parameters and return type, and then implement the add_tag of a and B respectively.
 
However, in the concept of closures, add_tag is a function that requires two parameters: tag_name and content, but the tag_name parameter is packed. So you can tell me how to pack the package at the beginning and then take it away.
 
The above example is not very vivid. In fact, in our life and work, the concept of closure is also very common. For example, when dialing a mobile phone, you only care about who the phone number is, instead of worrying about how the phone number of each brand is implemented and what modules are used. For example, if you go to a restaurant for dinner, you only need to pay for the meal and enjoy the service. you don't know how much waste of oil is used for the meal. These functions can be regarded as closures, and some functions or services (call and meal) are returned, but these functions use external variables (antennas, gutter oil, etc ).
 
You can also think of a class instance as a closure. when you construct this class, different parameters are used. These parameters are the packages in the closure, the method provided by this class is the closure function. But the class is much larger than the closure, because the closure is only a executable function, but the class instance may provide many methods.
 
When to use closure
 
Actually, closures are very common in Python, but you don't pay special attention to them. For example, Decorator in Python. if you need to write a Decorator with parameters, a closure is usually generated.
 
Why? Because the Python decorator is a fixed function interface form. It requires that your decorator function (or decorator class) must accept a function and return a function:
 
# How to define def wrapper (func1): # accept a callable object return func2 # return an object, which is generally a function # how to use def target_func (args ): # target function pass # Call Method 1: directly wrap result = wrapper (target_func) (args) # Call method 2. use the @ syntax, equivalent to Method 1 @ wrapper def target_func (args): pass result = target_func ()
 
What if your decorator has parameters? Then you need to package another layer on the original decorator to receive these parameters. After these parameters (private goods) are passed to the inner decorations, the closure is formed. Therefore, when your decorator requires custom parameters, a closure is usually formed. (Except for the class decorator)
 
Def html_tags (tag_name): def wrapper _ (func): def wrapper (* args, ** kwargs): content = func (* args, ** kwargs) return "<{tag }>{ content}
 ". Format (tag = tag_name, content = content) return wrapper _ @ html_tags ('B') def hello (name = 'Toby'): return 'Hello {}! '. Format (name) # The syntax of @ is as follows # hello = html_tag ('B') (hello) # html_tag ('B') is a closure that accepts a function, and returns a function print hello ()#Hello Toby!Print hello ('world ')#Hello world! 
For more in-depth analysis of the decorator, you can refer to another blog I wrote.
 
Further exploration
 
In fact, it does not need to be too deep. to understand the above concepts, there are a lot of code that seem to be a headache.
 
Next let's take a look at what the closure package looks like. In fact, the closure function will have an extra _ closure _ attribute relative to the normal function. it defines a tuples used to store all cell objects, each cell object stores all the external variables in this closure.
 
>>> Def make_printer (msg1, msg2): def printer (): print msg1, msg2 return printer >>>> printer = make_printer ('foo', 'bar ') # form a closure >>> printer. _ closure _ # return cell tuples (
 
  
,
  
   
) >>> Printer. _ closure _ [0]. cell_contents # The first external variable 'foo' >>> printer. _ closure _ [1]. cell_contents # Second external variable 'bar'
  
  
The principle is so simple.