In general, the concept of closures is involved in many languages. Simply put, closures obtain different results based on different configuration information. next we will talk about closures in Python.
Closures in Python
A few days ago, someone left a message about one of them.Closure
Andre.sub
Is not clear. I searched at my feet and found that I didn't write anything related to closures. so I decided to summarize and improve Python content.
1. concepts of closures
First, we have to start with the basic concept. what is a closure? Let's take a look at the explanation on the Wikipedia:
The code is as follows:
In computer science, Closure is short for Lexical Closure, a function that references free variables. This referenced free variable will exist with this function, even if it has left the environment where it was created. Therefore, there is another saying that a closure is an entity composed of a function and its reference environment. A closure can have multiple instances at runtime. different reference environments and the same function combination can generate different instances.
....
The two key points mentioned above are free variables and functions. I still have to repeat the meaning of "closure". I hope I can understand it as a closed package. this package is a function, and of course the internal logic of the function, the items in the package are free variables, which can wander around with the package. Of course, there must be a premise that this package was created.
In the Python language, A closure is that you call function A, and function A returns function B to you. The returned function B is called a closure. The parameter you pass when calling function A is A free variable.
For example:
def func(name): def inner_func(age): print 'name:', name, 'age:', age return inner_funcbb = func('the5fire')bb(26) # >>> name: the5fire age: 26
When func is called, a closure -- inner_func is generated and the closure holds the free variable -- name. Therefore, this means that after the lifecycle of the function func ends, the name variable still exists because it is referenced by the closure and will not be recycled.
In addition, closures are not a special concept in Python. all languages that use functions as first-class citizens have the concept of closures. However, closures can also be used in languages like Java where class is the first-class citizen, but they must be implemented using classes or interfaces.
For more conceptual information, refer to the final reference link.
2. why use closures?
Based on the above introduction, I don't know if the reader feels similar to the class. The similarity is that they provide data encapsulation. The difference is that the closure itself is a method. Like classes, we often abstract common things into classes during programming (and, of course, we also model the real world-business) to reuse common functions. The same is true for closures. when we need to abstract the granularity of functions, closures are a good choice.
At this point, the closure can be understood as a read-only object. you can pass an attribute to it, but it can only provide you with an interface for execution. Therefore, in the program, we often need such a function object -- closure to help us complete a common function, such as the -- decorator mentioned later.
3. use closures
The first scenario is the decorator, which is very important and common in python. Python provides a friendly "syntax sugar" for the decorator "--@, we can easily use the decorator. the decoration principle is not described too much. Simply put, adding @ decorator_func to a function func is equivalent to decorator_func (func ):
Def decorator_func (func): def wrapper (* args, ** kwargs): return func (* args, ** kwargs) return wrapper @ decorator_funcdef func (name ): print 'My name is ', name # is equivalent to decorator_func (func)
In this example of the decorator, the closure (wrapper) holds the external func parameter, and can accept the externally passed parameters. the accepted parameters are passed to func intact, and return the execution result.
This is a simple example. a slightly more complex point can have multiple closures, such as the LRUCache decorator that is frequently used. the decorator can accept the parameter @ lru_cache (expire = 500. The implementation is the nesting of two closures:
Def lru_cache (expire = 5): # default 5s timeout def func_wrapper (func): def inner (* args, ** kwargs ): # cache processing bala return func (* args, ** kwargs) return inner return func_wrapper @ lru_cache (expire = 10*60) def get (request, pk) # omitting the specific code return response ()
Those who do not know the closure must be able to understand the above code. this is an interview question we often asked before.
The second scenario is based on a feature of the closure-"evaluate inertia ". This application is common when accessing databases, for example:
# Pseudocode indicates class QuerySet (object): def _ init _ (self, SQL): self. SQL = SQL self. db = Mysql. connect (). corsor () # Pseudocode def _ call _ (self): return db.exe cute (self. SQL) def query (SQL): return QuerySet (SQL) result = query ("select name from user_app") if time> now: print result # then the database access is executed.
The above example shows how to use a closure to evaluate the inertia. However, the result returned by the preceding query is not a function, but a class with function functions. If you are interested, you can see the implementation of Django's queryset. The principle is similar.
In the third scenario, you need to assign values to the parameters of a function in advance. of course, there is a good solution to accessing functools. parial in Python, but it can also be implemented using closures.
Def partial (** outer_kwargs): def wrapper (func): def inner (* args, ** kwargs): for k, v in outer_kwargs.items (): kwargs [k] = v return func (* args, ** kwargs) return inner return wrapper @ partial (age = 15) def say (name = None, age = None ): print name, agesay (name = "the5fire") # of course, using functools is much simpler than this # Just Need: functools. partial (say, age = 15) (name = 'the5fire ')
This seems to be a far-fetched example, but it is also a practice of the closure application.
Finally, the closure is easy to understand and widely used in Python. This article is a summary of the closure. if you have any questions, please leave a message.
4. References
Wikipedia-closure
Http://stackoverflow.com/questions/4020419/closures-in-python
Http://www.shutupandship.com/2012/01/python-closures-explained.html
Http://stackoverflow.com/questions/141642/what-limitations-have-closures-in-python-compared-to-language-x-closures
Http://mrevelle.blogspot.com/2006/10/closure-on-closures.html