【问题标题】:Understanding a lambda function reformatting for closure了解 lambda 函数重新格式化以进行闭包
【发布时间】:2019-11-02 01:06:20
【问题描述】:

我最近遇到了一个问题,我在 .connect 的 pyqt 的 for 循环中使用 lambda 函数。这导致了 lambda 函数中的闭包问题,我能够使用 functools 解决它,但经过更多研究后,我发现我可以使用不需要导入 functools 的稍微不同的代码。

使用以下格式的示例代码:

for i in range(0,len(items)):
     items[i].connect( ( lambda i: lambda: func(i) )(i) )

def func(i):
    print('i value ' + str(i))

我不确定为什么会这样。

我试过了

for i in range(0,len(items)):
     items[i].connect( lambda i=i: func(i) )

def func(i):
    print('i value ' + str(i))

而这只给出了 i 的第一个值。第一个示例完全按照我的意愿工作,但我不明白它在做什么。据我了解,它返回一个在调用之前用 i 评估的函数,但是我不明白 lambda 括号外的 (i) 是做什么的。我也不明白为什么第二个例子对我不起作用。

任何帮助将不胜感激,谢谢。

【问题讨论】:

    标签: python lambda closures


    【解决方案1】:

    Python 中,第二个示例中的 lambda 定义中的 i=i 等默认值仅在评估函数定义时评估一次(并非每次解释语句时)。这意味着i 在第一次迭代时被分配,然后永远不会改变。

    在您的第一个示例中,它可以工作,因为 lambda 的定义没有任何默认值,并且在循环的每次迭代中都会评估一个新的 lambda 定义。使用括号是因为您在每次迭代中执行最外层的 lambda,传递它i,它返回最内层的 lambda。如果在每个闭包中使用不同的变量名,则更容易阅读:

    for i in range(0, len(items)):
         items[i].connect( ( lambda x: lambda: func(x) )(i) )
    

    【讨论】:

      猜你喜欢
      • 2015-02-09
      • 1970-01-01
      • 1970-01-01
      • 2022-01-24
      相关资源
      最近更新 更多