In the application of computer programming , Closure (Closure) It's lexical closure (Lexical Closure) For short , It's a function that references a free variable . This referenced free variable will exist with this function , Even if it has left the environment in which it was created . So there is another saying , It is considered that a closure is an entity composed of a function and its related reference environment . Closures can have multiple instances at run time , Different reference environments and the same function combination can produce the same instance .
According to the literal meaning , A closure can be vividly understood as a closed package , This package is a function , Of course, there is also the logic corresponding to the function , What's inside the package is the free variable , Free variables can wander around with packages . Of course, there must be a premise , This package was created . stay Python In language , A closure is when you call a function A, This function A Returns a function B Here you are. . This returned function B It's called closure . You're calling functions A When , The parameter passed is a free variable . For example, the following example code demonstrates the specific process of generating a closure
def func (name):
def inner_func (date):
print ('name: ',name, 'date:', date)
return inner_func
bb= func(' Summer vacation ')
bb (71)
In the example code above , When a function is called func( And then there's a closure :inner_func(), And the closure has free variables “name”. This means that when the function func() After the end of its life cycle , Variable name It will still exist , Because it's referenced by closures , So it won't be recycled . After execution, you will lose Be careful : Closure is not Python A concept peculiar to language , All take functions as “ First class citizen ” All languages have the concept of closures . But like Java In this way class by “ First class citizen ” You can also use closures in the language of , It's just that it has to be implemented in a class or interface .
in addition , If you explain from the form of expression Python Closure in , If in an internal function , For external scope ( But one is in the global scope ) The variables are quoted , So internal functions are considered closures . This explanation is very easy to understand , Unlike other definitions, there are a lot of strange nouns , Not for beginners . Be careful : The similarities and differences between closures and classes
Based on the previous Introduction , I believe that readers have found that closures and classes are somewhat similar , The similarity is that they both provide encapsulation of data . The difference is that the closure itself is a method . Like the class , When we program, we often abstract common things into classes ( Of course , And the real world — Business modeling ), To reuse common functions . The same goes for closures , When we need the abstraction of function granularity , Closures are a good choice . At this point, a closure can be understood as a read-only object , You can pass it an attribute , But it can only provide you with an execution interface . So we often need such a function object in the program —— Closures to help us accomplish a common function , For example, the decorator mentioned earlier .
stay Python In language , A closure is an object obtained by packaging the statements that make up a function and the execution environment of these statements . When using nested functions ( Functions are defined in functions ) when , Closures capture the entire environment required for the execution of internal functions . Besides , Nested functions can use any variable in the nested function , Just like ordinary functions can reference global variables , It is not necessary to introduce... Through parameters .
For example, in the following example code , Demonstrates the process that nested functions can use any variable in the nested function .
x=14 # Define global variables x
def foo() : # Define the outer functions of nested functions foo()
x=50
def bar() : # Define a variable x The initial value of 3
print('x The value of is :%d' %x) # Define nested inner functions bar()
print(' The plan for the summer vacation is to learn %d' %x,' God ') # Quoted variables X
bar () # Call nested inner functions bar()
if __name__ == '__main__':
foo() # Call the outer function of the nested function foo()
A global variable is defined in the above example code x, In the outer layer of the nested function foo A variable is also defined in x: In nested inner functions bar() Variables referenced in x Should be foo() As defined in x. Because nested functions can directly reference variables defined in their outer functions x And output , So the output value is 50, Instead of global variables x Value 14. After execution, it will output :
In order to understand Python Knowledge of closures , Here is an example of nested function calls inside and outside . We can think of this example as statistics
A function of function calls . Can be count[0] Think of it as a counter , Every time the function is executed hello(), count[0] The value of plus 1. The specific implementation code is as follows .
def hellocounter (name) :
count=[0]
def counter () :
count[0]+=1
print ('Hello, ',name, ',',str (count[0])+' access!')
return counter
hello = hellocounter (' Summer vacation ')
hello()
hello()
hello()
In the example code above , Some readers may ask questions : Why not just write count, And using a list ? This is actually Python2 One of the bug, If you don't use the list , The following error will be reported .UnboundLocalError: local variable 'count' referenced before assignment.
The above error means that the variable count Without definition, it directly refers to , So in Python 3 A keyword is introduced in nonlocal, The function of this keyword is to tell Python Program , This count Variables are defined externally , then Python Will go to the outer function to find variables count, Then I found count=0 This one Meaning and assignment , In this way, the program can be executed normally . After execution, it will output :