我正在构建一个游戏,为了让它发挥作用,我需要生成一个预先构建的#34;或者"准备打电话"表达式。我尝试使用lambda表达式执行此操作,但遇到了生成查找表的问题。我的代码类似于以下内容:
import inspect
def test(*args):
string = "Test Function: "
for i in args:
string += str(i) + " "
print(string)
funct_list = []
# The problem is in this for loop
for i in range(20):
funct_list.append(lambda: test(i, "Hello World"))
for i in funct_list:
print(inspect.getsource(i))
我得到的输出是:
funct_list.append(lambda: test(i, "Hello World"))
funct_list.append(lambda: test(i, "Hello World"))
funct_list.append(lambda: test(i, "Hello World"))
funct_list.append(lambda: test(i, "Hello World"))
...
我需要它去:
funct_list.append(lambda: test(1, "Hello World"))
funct_list.append(lambda: test(2, "Hello World"))
funct_list.append(lambda: test(3, "Hello World"))
funct_list.append(lambda: test(4, "Hello World"))
...
我尝试了以下两种方法但都没有工作
for i in range(20):
funct_list.append(lambda: test(i, "Hello World"))
for i in range(20):
x = (i, "Hello World")
funct_list.append(lambda: test(*x))
我的问题是如何生成lambda表达式列表,其中已经设置了lambda表达式中的一些变量。
答案 0 :(得分:2)
正如其他人所提到的,Python的闭包是后期绑定,这意味着来自闭包中引用的外部作用域的变量(换句话说,变量关闭< / em>)在调用闭包时被查找,并且在定义时不。
在您的示例中,当您的lambda从外部作用域引用变量i
时,将形成有问题的闭包。但是,当稍后调用lambda时,循环已经完成并将变量i
保留为值19。
一个简单但不是特别优雅的修复方法是使用lambda的默认参数:
for i in range(20):
funct_list.append(lambda x=i: test(x, "Hello World"))
与闭包变量不同,默认参数是早期绑定的,因此在lambda定义时获得了捕获变量i
的值所需的效果。
更好的方法是使用functools.partial
,它允许你部分应用函数的一些参数,&#34;修复&#34;他们达到一定的价值:
from functools import partial
for i in range(20):
funct_list.append(partial(lambda x: test(x, "Hello World"), i))