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]
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]
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]
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 _wrapper
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!