11

我有 C++ 的背景并尝试学习一些 python。

虽然我了解 C++ 的虚函数,但不幸的是,我不明白 python 中闭包的后期绑定是什么意思。

链接:https ://gist.github.com/deemson/8efabf56d67623ead804 (不再有效)

从教程复制粘贴:

functions = []
for n in [1, 2, 3]:
    def func(x):
        return n*x
    functions.append(func)

# You would expect this to print [2, 4, 6]
print(
    'calling a list of bad closures and output is: {}'
    .format(str([function(2) for function in functions]))
)

这里到底发生了什么?当函数附加到列表中时,它有什么值?有人可以简化这段代码让我理解吗?

4

2 回答 2

9

请注意这一点,您可以在运行时创建函数,或多或少像lambdas在 c++ 中一样。所以基本上你是在迭代一个列表,使n取值1,2 and 3

for n in [1, 2, 3]:
    def func(x):
        return n*x

因此,通过每次迭代,您都在构建一个名为 func 的函数,它接受一个值并将其乘以 n。通过将其附加到函数列表,您将存储此函数,因此您可以遍历列表以调用函数。

[function(2) for function in functions]

通过这样做,你调用每个存储有 value 的函数2,你会期望 this 输出[2, 4, 6]([1*2, 2*2, 3*2]),但它会返回[6, 6, 6],为什么?,因为每个函数都n用于它的计算,所以他们并没有真正在做1*x, 2*x and 3*x,但实际上n*x并且因为n上次绑定到3所有功能正在做的事情3*2变成了6

玩弄 python 控制台以正确检查它。

于 2016-04-06T22:45:28.173 回答
3

在 C++ 语言中,指向函数的指针是附加到列表中的内容。在for循环之后,functions包含指向三个不同函数(func(x) = n * xfunc(x) = n * xfunc(x) = n * x的指针。注意对 n 的依赖。随着 n 的变化,这些函数的行为也会发生变化,并且它们都是等价的。

在代码的第二部分中,指针从列表中提取出来,三个函数中的每一个都使用参数进行评估2

这是一个进一步的例子来澄清。想象一下我们这样做:

>>> functions
[<function func at 0x0239AA70>, <function func at 0x0239AAB0>, <function func at 0x0239AB30>]
>>> g = functions[2]
>>> g
<function func at 0x0239AB30>
>>> g(10)
20
>>> g(100)
200

我们在第一行看到的是函数包含指向三个不同函数的指针。下一行从列表中提取第三个指针(指向func(x) = n * x)并将其分配给 g。实际上,我们已经g(x) = n * x用这个调用定义了一个函数。我们现在可以g使用参数进行评估。

请注意,由于所有函数都依赖于n,因此您可以更改n,并且行为也会更改。

>>> n = 100
>>> g(10)
1000
于 2016-04-06T22:50:17.847 回答