了解lambda函数重新格式化以进行关闭

时间:2019-06-19 10:08:00

标签: python lambda closures

最近遇到一个问题,我在for循环中使用.connect在pyqt中使用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)的作用。我也不明白为什么第二个例子对我不起作用。

谢谢您的任何帮助。

1 个答案:

答案 0 :(得分:0)

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) )