gpt4 book ai didi

python - lambda 函数闭包捕获了什么?

转载 作者:IT老高 更新时间:2023-10-28 12:12:32 28 4
gpt4 key购买 nike

最近我开始使用 Python,并且发现了闭包工作方式中的一些特殊情况。考虑以下代码:

adders=[None, None, None, None]

for i in [0,1,2,3]:
adders[i]=lambda a: i+a

print adders[1](3)

它构建了一个简单的函数数组,这些函数接受单个输入并返回该输入加上一个数字。这些函数在 for 循环中构造,其中迭代器 i0 运行到 3。对于这些数字中的每一个,都会创建一个 lambda 函数,该函数会捕获 i 并将其添加到函数的输入中。最后一行以 3 作为参数调用第二个 lambda 函数。令我惊讶的是,输出是 6

我希望是 4。我的理由是:在 Python 中,一切都是对象,因此每个变量都是指向它的指针。在为 i 创建 lambda 闭包时,我希望它存储一个指向当前由 i 指向的整数对象的指针。这意味着当 i 分配一个新的整数对象时,它不应该影响之前创建的闭包。可悲的是,在调试器中检查 adders 数组表明确实如此。所有 lambda 函数都引用 i 的最后一个值 3,这导致 adders[1](3) 返回 6.

这让我想知道以下几点:

  • 闭包究竟捕获了什么?
  • 说服 lambda 函数以在 i 改变它的值?

对于更易于理解、更实用的问题版本,特定于使用循环(或列表理解、生成器表达式等)的情况,请参阅 Creating functions (or lambdas) in a loop (or comprehension) .这个问题的重点是理解 Python 中代码的底层行为。

如果您在这里尝试解决在 Tkinter 中制作按钮的问题,请尝试 tkinter creating buttons in for loop passing command arguments获取更具体的建议。

What exactly is contained within a obj.__closure__?了解如何 Python 实现闭包的技术细节。见 What is the difference between Early and Late Binding?用于相关术语的讨论。

最佳答案

您可以使用具有默认值的参数强制捕获变量:

>>> for i in [0,1,2,3]:
... adders[i]=lambda a,i=i: i+a # note the dummy parameter with a default value
...
>>> print( adders[1](3) )
4

想法是声明一个参数(巧妙地命名为i)并给它一个你要捕获的变量的默认值(i的值)

关于python - lambda 函数闭包捕获了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2295290/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com