A brief talk about closures in Python _python

Source: Internet
Author: User
Tags closure wrapper in python

Closures in Python

A few days ago another message, about one 闭包 re.sub of the use is not very clear. I searched the cloud community and found nothing about closures, so I decided to summarize and refine Python's content.

1. The concept of closures

First of all, from the basic concept, what is closure? Take a look at the wiki explanation:

Copy Code code as follows:
In computer science, closures (Closure) are abbreviations for lexical closures (lexical Closure), which are functions that refer to free variables. The referenced free variable will exist with this function, even if it has left the environment that created it. So, there is another saying that closures are entities that are combined by functions and reference environments associated with them. Closures can have multiple instances at run time, and different reference environments and the same combination of functions can produce different instances.
....

The above mentioned two key places: free variables and functions, these two key points later. Still have to repeat the meaning of "closure", Wang Wen know the meaning, can be image of it as a closed package, this package is a function, of course, there is a function of the internal corresponding logic, the package inside the thing is a free variable, free variable can be wandering around with the package. Of course, there must be a premise that this package was created.

In the language of Python, a closure is where you call a function A, and this function a returns a function B to you. The return function B is called a closure. The argument you pass when you call function A is a free variable.

As an example:

def func (name):
 def inner_func (age):
  print ' name: ', Name, ' Age: ', the Age return
 inner_func

bb = func (' The5fire ')
BB # >>> Name:the5fire age:26

This is when the call to Func produces a closure--inner_func, and the closure holds the free variable--name, so it also means that when the function func lifecycle is over, the name variable still exists because it is referenced by the closure and is not recycled.

In addition, closures are not a unique concept in Python, and all languages that function as first-class citizens have the concept of closures. However, a closure can also be used in a language like Java for class-class citizens, but it has to be implemented with classes or interfaces.

More conceptual things can refer to the final reference link.

2. Why use closures

Based on the above introduction, I do not know whether the reader has a feeling that this thing is similar to the class, the similarity is that they all provide a package of data. The difference is that the closure itself is a method. Like classes, we often abstract common things into classes in programming, (and, of course, modeling the real world-business) to reuse common functionality. Closures are also the same, and when we need the abstraction of function granularity, closures are a good choice.

At this point the closure can be understood as a read-only object, and you can pass a property to him, but it can only provide you with an executing interface. So in the program we often need such a function object--closure, to help us complete a common function, such as the later mentioned--adorners.

3. Using closures

The first scenario, one of the most important and common use scenarios in Python, is the adorner, which provides a friendly "syntactic sugar"--@ for the adorner, making it easy to use the adorner, and the principle of decoration is not overly elaborate, In short, you add @decorator_func to a function func, which is equivalent to Decorator_func (func):

def decorator_func (func):
 def wrapper (*args, **kwargs): Return
  func (*args, **kwargs) return
 wrapper

@decorator_func
def func (name):
 print ' My name is ', name

# equivalent to
Decorator_func (func)

In this example of the adorner, the closure (wrapper) holds the external func parameter and is able to accept the externally transmitted parameters, and the accepted parameters are passed back to the Func, and the execution results are returned.

This is a simple example of a slightly more complex point where you can have multiple closures, such as the LRUCache adorner that you use frequently, and you can accept parameters @lru_cache (expire=500) on the adorner. 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 handling Bala Bala Bala return
   func (*args, **kwargs) return
  inner return
 func_wrapper

@lru_cache (expire= 10*60)
def get (request, PK)
 # Omit specific code return
 response ()

Students who do not understand the closure must be able to understand the above code, this is the interview we have often asked the face questions.

The second scenario is an attribute based on closures-"lazy evaluation". This application is more common in the database access, such as:

# pseudo code to indicate

class QuerySet (object):
 def __init__ (self, SQL):
  self.sql = sql
  self.db = Mysql.connect (). Corsor () # pseudo code

 def __call__ (self): return
  Db.execute (self.sql)

def query (SQL): Return
 QuerySet (SQL) Result

= Query (' Select name from User_app ')
if time > Now:
 print result # then perform database access

This less-than-appropriate example shows the ability to perform lazy evaluation through closures, but the result from query above is not a function, but a class with functional functions. Interested to see the implementation of the Django Queryset, the principle is similar.

The third scenario, which requires an early assignment of the parameters of a function, certainly has a good solution to access functools.parial in Python, but it can be done with 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,

age Say (name= "The5fire")
# Of course, Functools is much simpler than this.
# only need: Functools.partial (say, age=15) (name= ' The5fire ')

It seems to be a far-fetched example, but it's also a practice of closures.

Finally, the closure of this thing is easy to understand, the application in Python is also very extensive, this article is a summary of the closure, there are any questions welcome message exchange.

4. Reference materials

Wikipedia-closures

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

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.