# Python Tutorial - Closures

Python Exercise Lists

Closures, also known as closure functions or closed functions, are actually similar to the nested functions mentioned earlier, except that the external function in the closure does not return a specific value but a function. Under normal circumstances, the returned function is assigned to a variable, which can be executed and called later.

For example, to calculate the nth power of a number, a closure can be written as the following code:

```#Closure function, where exponent is called a free variable
def nth_power (exponent):
def exponent_of (base):
return base ** exponent
return exponent_of # The return value is the exponent_of function
square = nth_power (2) # Calculate the square of a number
cube = nth_power (3) # calculate the cube of a number
print (square (2)) # Calculate the square of 2
print (cube (2)) # calculate the cube of 2
```

The output is:

4
8

In the above program, the return value of the external function nth_power is the function exponent_of, not a specific value.

It should be noted that after executing square = nth_power (2) and cube = nth_power (3), the parameter exponent of the external function nth_power () is assigned to square and cube together with the internal function exponent_of, so that square (2) is called afterwards ) Or cube (2), the program can output the result smoothly without error that the parameter exponent is not defined.

Seeing this, readers may ask, why do we need closures? The above program can be written in the following form:

```def nth_power_rewrite (base, exponent):
return base ** exponent
```

The above program can indeed achieve the same function, but using closures can make the program more concise and readable. Imagine, for example, that you need to calculate the square of many numbers, so which of the following forms does the reader think is better?

```# Do not use closures
res1 = nth_power_rewrite (base1, 2)
res2 = nth_power_rewrite (base2, 2)
res3 = nth_power_rewrite (base3, 2)
# Using closures
square = nth_power (2)
res1 = square (base1)
res2 = square (base2)
res3 = square (base3)
```

Obviously, the second way is more concise. You can input one less parameter each time you call the function.

Second, similar to the advantages of reducing nested functions, the function needs to do some extra work at the beginning. When the function needs to be called multiple times, if the extra work code is placed in an external function, it can reduce unnecessary overhead to improve the efficiency of program operation.

## __Closure__ Attribute of Python Closures

Closures have one more __closure__ attribute than ordinary functions, which records the address of a free variable. When the closure is called, the system will find the corresponding free variable according to the address and complete the overall function call.

Take nth_power as an example, when it is called, you can use the __closure__ attribute to get the address stored by the free variable (that is, the exponent parameter in the program), for example:

```def nth_power(exponent):
def exponent_of(base):
return base ** exponent
return exponent_of
square = nth_power(2)
#View the value of __closure__
print (square.__closure__)
```

The output is:

(cell at 0x000001D83C680BE8: int object at 0x00007FF821969360,)

As you can see, the displayed content is an int integer type, which is the initial value of the free variable exponent in square. You can also see that the type of the __closure__ attribute is a tuple, which indicates that a closure can support the form of multiple free variables.