Home > Article > Backend Development > What is a closure? Two solutions to problems about python closures
Closure is to obtain different results based on different configuration information. Here are two things to note about Python closures through this article. Friends in need can refer to it
What is a closure?
Simple Said, closure is to obtain different results based on different configuration information.
Let’s take a look at the professional explanation: Closure is the abbreviation of Lexical Closure, which is quote of a free variable function. The referenced free variable will remain with the function even after it has left the environment in which it was created. Therefore, there is another way of saying that a closure is an entity composed of a function and its associated reference environment.
Lazy binding
External free variables referenced by Python closure functions are delayed bound. PythonIn [2]: def multipliers(): ...: return [lambda x: i * x for i in range(4)] In [3]: print [m(2) for m in multipliers()] [6, 6, 6, 6] In [2]: def multipliers(): ...: return [lambda x: i * x for i in range(4)] In [3]: print [m(2) for m in multipliers()] [6, 6, 6, 6]Such as the above code: i is a free variable in the external scope referenced by the closure function, which will only be ## when the internal function
is called #Search for the value of variable i. Since the loop has ended and i points to the final value 3, each function call gets the same result. Solution:
1) Bind immediately when generating the closure function (Use the default value of the function
formal parameter):In [5]: def multipliers(): return [lambda x, i=i: i* x for i in range(4)] ...: In [6]: print [m(2) for m in multipliers()] [0, 2, 4, 6] In [5]: def multipliers(): return [lambda x, i=i: i* x for i in range(4)] ...: In [6]: print [m(2) for m in multipliers()] [0, 2, 4, 6]Such as the above code: When generating a closure function, you can see that each closure function has a parameter with a default value: i=i, at this time, the interpreter will Find the value of i and assign it to the formal parameter i. In this way, in the outer scope of the generated closure function (that is, in the outer loop), the variable i is found, and its current value is assigned to the formal parameter i. 2) Use functools.partial:Python
In [26]: def multipliers(): return [functools.partial(lambda i, x: x * i, i) for i in range(4)] ....: In [27]: print [m(2) for m in multipliers()] [0, 2, 4, 6] In [26]: def multipliers(): return [functools.partial(lambda i, x: x * i, i) for i in range(4)] ....: In [27]: print [m(2) for m in multipliers()] [0, 2, 4, 6]Such as the above code: When there may be problems due to delayed binding, you can construct it through functools.partial Partial functions allow free variables to be bound to closure functions first. Prohibit rebinding of referenced free variables within the closure function
Python
def foo(func): free_value = 8 def _wrapper(*args, **kwargs): old_free_value = free_value #保存旧的free_value free_value = old_free_value * 2 #模拟产生新的free_value func(*args, **kwargs) free_value = old_free_value return _wrapper def foo(func): free_value = 8 def _wrapper(*args, **kwargs): old_free_value = free_value #保存旧的free_value free_value = old_free_value * 2 #模拟产生新的free_value func(*args, **kwargs) free_value = old_free_value return _wrapperThe above code will Error reported, UnboundLocalError: local variable 'free_value' referenced before assignment, the above code is intended to implement an initialization
state
(free_value) but can be changed as needed when executing the internal closure function The decorator of the new state (free_value = old_free_value * 2), but due to internal rebinding, the interpreter will treat free_value as a local variable. If old_free_value = free_value, an error will be reported, because the interpreter thinks that free_value is assigned without a value. Cited.When you plan to modify the free variable referenced by the closure function, you can put it into a list, so that free_value = [8], free_value cannot be modified , but free_value[0] can be modified safely
.In addition, Python 3.x added the nonlocal keyword, which can also solve this problem.
【Related recommendations】1.Python Free Video Tutorial
2. Python Learning Manual
3. python object-oriented video tutorial
The above is the detailed content of What is a closure? Two solutions to problems about python closures. For more information, please follow other related articles on the PHP Chinese website!