【问题标题】:What does "late binding closures" mean? [duplicate]“后期绑定闭包”是什么意思? [复制]
【发布时间】:2016-07-27 14:04:08
【问题描述】:

我有 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]))
)

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

【问题讨论】:

    标签: python python-closures


    【解决方案1】:

    请注意,您可以在运行时创建函数,或多或少类似于 c++ 中的lambdas。所以基本上你是在遍历一个列表,使 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]
    

    通过这样做,您调用每个存储值 2 的函数,您会期望它输出 [2, 4, 6] ([1*2, 2*2, 3*2]),但它会返回 @ 987654328@, WHY?, 那是因为每个函数都使用n 进行计算,所以他们并没有真正在做1*x, 2*x and 3*x,但实际上n*x 并且由于n 上次绑定到3 所有函数都在做3*2 变成 6

    使用 python 控制台进行检查以正确检查它。

    【讨论】:

      【解决方案2】:

      在 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
      

      【讨论】:

      • 但这不会产生 [2 4 6] 而不是 [6 6 6]
      • 丹尼尔的回答是正确的——他抓住了我没有抓住的东西。它们都引用 n,并且由于 n 最终确定为 2,因此所有函数的行为方式完全相同。
      • 我已经修改以提及对 n 的依赖,并留下解决方案以阐明与 C++ 中指针的连接。
      猜你喜欢
      • 1970-01-01
      • 2019-09-12
      • 2015-01-22
      • 2023-03-22
      • 2020-10-27
      • 2015-07-15
      • 2018-07-17
      • 2012-08-13
      • 1970-01-01
      相关资源
      最近更新 更多