如何强制Python在循环中创建新变量/新范围?
今天我探索了Python的一种奇怪行为。例如:如何强制Python在循环中创建新变量/新范围?,python,variables,for-loop,parameters,closures,Python,Variables,For Loop,Parameters,Closures,今天我探索了Python的一种奇怪行为。例如: closures = [] for x in [1, 2, 3]: # store `x' in a "new" local variable var = x # store a closure which returns the value of `var' closures.append(lambda: var) for c in closures: print(c()) 上面的代码打印出来 3 3
closures = []
for x in [1, 2, 3]:
# store `x' in a "new" local variable
var = x
# store a closure which returns the value of `var'
closures.append(lambda: var)
for c in closures:
print(c())
上面的代码打印出来
3
3
3
但我想把它打印出来
1
2
3
我为自己解释了这种行为,
var
始终是同一个局部变量(python不像其他语言那样创建新的局部变量)。如何修复上述代码,使每个闭包返回另一个值?您不能在循环的局部范围内创建新变量。无论选择什么名称,函数都将始终是该名称的闭包,并使用其最新值
最简单的方法是使用关键字参数:
closures = []
for x in [1, 2, 3]:
closures.append(lambda var=x: var)
最简单的方法是为lambda使用默认参数,通过这种方式,
x
的当前值被绑定为函数的默认参数,而不是在每次调用时在包含范围中查找var
:
closures = []
for x in [1, 2, 3]:
closures.append(lambda var=x: var)
for c in closures:
print(c())
或者,您可以创建一个闭包(您拥有的不是闭包,因为每个函数都是在全局范围内创建的):
make_closure()
也可以这样编写,这样可以使其更具可读性:
def make_closure(var):
return lambda: var
在您的示例中,
var
始终绑定到循环的最后一个值。您需要使用closures.append(lambda var=var:var)
将其绑定到lambda内部 提示:什么在Python中引入了一个新的变量作用域?刚才看到的是一个重复的问题。我怎样才能关闭这个问题,还是删除它?@tampis:投票关闭吧——主持人最终会决定这个问题是合并还是删除。事实上,我不认为这和你所想的一样。尝试在第一个循环后添加del-var
。@cha0sitedel-var
出现异常未定义全局名称“var”
感谢您的编辑,现在+1就可以了。
def make_closure(var):
return lambda: var