Closure functions in python and closure functions in python

Source: Internet
Author: User

Closure functions in python and closure functions in python

Preliminary Exploration of closure Functions

Normally, we define functions in this way.

def foo(): pass

In function programming, functions can also be nested, as shown below:

def foo(): print("hello world in foo")  def bar(): print("hello world in bar")

Now we call the foo function. What will the execution result look like ??

hello world in foo

As shown above, only the first function of the foo function is executed, and the bar function is not executed. Why?

In fact, no matter which part of the function is written, it only defines a function. Only when this function is called can the internal statements of the function be executed.

In the above example, although the bar function is defined inside the foo function, it is not executed, so the bar function will not be executed, does a function defined in a function have no function purpose ?? This is not the case.

Let's look at the following example and return the bar function as a value to the foo function to see the execution process.

def foo(): print("hello world in foo")  def bar(): print("hello world in bar") return barf1=foo()print(f1)

In this case, the bar function is returned to foo as a return value, so the execution result of the foo function has a return value.

At this time, define a variable f1 to receive the results returned by the foo function execution, and then print the f1

The returned result is as follows:

hello world in foo<function foo.<locals>.bar at 0x0000000002941A60>

The print Statement defined in the foo function is printed first, and the memory address of the bar function contained in the foo function is printed.

Since it is the memory address of a function, you can use parentheses to execute this function.

def foo(): print("hello world in foo") def bar(): print("hello world in bar") return barf1=foo()f1()

The execution result of this Code is:

hello world in foohello world in bar

Both print statements are printed.

In the preceding example, a function foo is defined first, and a function bar is nested in the foo function, and the function name of the function bar is returned, this is how closure functions are defined.

In fact, the definition of closure is that a function is nested inside the function.

Let's take a look at the following code.

 def foo(): print("hello world in foo") name="python" def bar():  print(name)  print("hello world in bar") return bar  f1=foo() f1()

In the preceding example, a variable name is defined in the outer function, and the variable name is printed in the internal function.

Execute the above Code. When printing the name variable, the variable name will be searched inside the bar function, but there is no name variable in the bar function,

In this case, according to the LEGB rule of the python variable search, the variable name will be searched on the outer layer of the bar function. At this time, the variable name can be found.

So the name value defined in The foo function is printed here.

Run the above Code and print the result as follows:

hello world in foopythonhello world in bar

The important thing to remember here is:

The inner function references the local variables of the outer function.

To analyze the execution process of the program in the above example:

First, run the foo function. The execution result of the foo function is the function name of the returned bar. At this time, the execution result of the foo function is defined as the variable f1,
In this case, f1 is equal to the memory address of the bar function, and then f1 runs with brackets, indicating that the bar function is run.
During bar function execution, bar function accesses the variables defined in the outer foo function. This is a typical closure function.
So what are the advantages of using closure functions ?? In the above example, the f1 value is the memory address of the bar function, and f1 is running with brackets.

Because f1 is a global variable, this means that the f1 function can be run anywhere in the entire program. At this time, another function is defined and the f1 function is called inside the function,

 def foo(): print("hello world in foo") name = "python"  def bar():  print(name)  print("hello world in bar") return bar  f1 = foo()  def func(): name = "aaaaa" f1() func()

To analyze the Program Execution Process:

1. when you run the func function, the program first applies for a space in the memory to save the value of the name variable, and then runs the f1 function. f1 is a global variable, so we can find the memory address of the f1 function.

2. When f1 is run with parentheses, a closure function is executed, which references the name variable.

3. the name variable has been defined outside the bar function. Therefore, when the f1 function, that is, the bar function, is called inside the func function, the referenced variable is still the name variable defined in the foo function, rather than the name variable defined in the func function,

4. because the f1 function contains the value of the name function, the variable name is defined in the func function, the execution result of the program still prints the name value defined in The foo function.

Program Execution result

hello world in foopythonhello world in bar

How to verify that a function is a closure function

First, the closure function has a unique attribute: closure

In the preceding example, print the _ closure _ attribute of f1.

 def foo(): name = "python" def bar():  print(name)  print("hello world in bar") return bar f1 = foo() print(f1.__closure__)

The output is as follows:

(<cell at 0x0000000001DF5708: str object at 0x0000000001E79688>,)

We can see that the printed result of the _ closure _ attribute is in the form of a tuple, and its value is the outer function scope of the f1 function.

In this case, you can call the cell_contents method of the elements returned by _ closure _ to print the value of the name variable.

 def foo(): name = "python"  def bar():  print(name)  print("hello world in bar") return bar  f1 = foo() print(f1.__closure__[0].cell_contents)

The output is as follows:

python

We can see that the program has printed the value of the name variable.

If the returned result of _ closure _ is a tuple, it must contain multiple values. See the following example.

Define multiple variables in the foo function, and then print the values of several variables in the bar function,

Then run the closure function to print the _ closure _ method of the closure function.

 def foo(): print("hello world in foo") name1 = "python1" name2 = "python2" name3 = "python3" name4 = "python4"  def bar():  print(name1)  print(name2)  print(name3)  print(name4)  print("hello world in bar") return bar  f1 = foo() print(f1.__closure__)

Program Execution result

(<cell at 0x0000000002145708: str object at 0x00000000021C9260>, <cell at 0x0000000002145A08: str object at 0x00000000021C93B0>, <cell at 0x0000000002145768: str object at 0x000000000295BE30>, <cell at 0x0000000002145C18: str object at 0x0000000002963880>)

Since four variables are defined in the foo function and these four variables are referenced in the bar function, the _ closure _ method of the closure function is printed, the returned tuples have four elements.

Now we can print the values of the four string objects in the returned tuples separately.

 def foo(): name1 = "python1" name2 = "python2" name3 = "python3" name4 = "python4"  def bar():  print(name1)  print(name2)  print(name3)  print(name4)  print("hello world in bar") return bar  f1 = foo() print(f1.__closure__[0].cell_contents) print(f1.__closure__[1].cell_contents) print(f1.__closure__[2].cell_contents) print(f1.__closure__[3].cell_contents)

Program Execution result

python1python2python3python4

So now there is still the last question, that is, must the inner function of the closure function be returned ??

Let's take a look at the following example:

 def foo(): name = "python1"  def bar():  print(name) print(bar.__closure__)  foo()

A nested function is defined, and the inner function of the nested function is not returned. Instead, the _ closure _ method of the inner function is printed and then the outer function is called directly.

Program Execution result

(<cell at 0x0000000002155708: str object at 0x00000000021D9688>,)

The variable object referenced by the inner function is still printed.

This indicates that the inner function of the closure function must return

Can the inner function of the closure function call global variables ??

Change the variable defined in the outer function to a global variable, and then reference this variable in the internal function.

 name = "python1" def foo(): def bar():  print(name)  print(bar.__closure__) f=foo() print(f)

Program Execution result

None
None

We can see that the execution result of the program is two None, and the value of the _ closure _ function of the inner function of the nested function is None.

This indicates that the global variable called by bar, the nested function of the foo function, is not successful. Therefore, the above example is not a closure function.

Summary of closure functions:

The closure is defined:

A function defined inside a function is called an internal function.
Internal functions call local variables of external functions.
Even if the internal function returns, you can still use local variables.
Usually, the inner function of the closure function is returned to the external function.
The external function of the closure function can be called anywhere, instead of being limited by the hierarchy when the function is defined.

Function of closure

1. built-in function scopes of closure Functions

In a normal sense, the order of variables to be searched during function execution is one layer outward, which complies with the LEGB (Local-> Enclose-> Global-> Built in) rule,

However, for the closure function, the variable search function only finds the layer outside the internal function, because the closure function itself has a scope, so as to conform to the meaning of the word "closure ".

2. latency calculation (also called inert computing)

See the following example.

 def func(): name="python" def bar():  print(name) return bar  f=func() print(f.__closure)

In the above example, the returned result of executing the foo () function is a function containing a built-in state. In fact, this function is not executed,

When you want to execute this built-in function in the future, you can execute the variable assigned to the result returned by func () in parentheses,

3. To keep a function in a state, you can use a closure.

Example:

 name="python"  def func(): print("I like %s" % name)  func()

The above code execution result will print a line: "I like python"

However, we know that calling the func function in different places may result in very different results.

If I want to call the func function wherever I like python,

You can use the closure.

 def func1():  name="python" def func():  print("I like %s" % name) return func func=func1() func()

As shown in, the func function contains a function func1, executes the func1 function, and assigns the returned result of the func1 function to the variable func.

At this time, func is a closure function, and the func function can be executed with brackets.

We must know that the execution result of the func function will print the "I like python" statement at this time, and the execution result will be the same no matter where the func function is called in the program.

Related Article

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.