如何强制 Python 在循环内创建新变量/新范围? [复制]
Posted
技术标签:
【中文标题】如何强制 Python 在循环内创建新变量/新范围? [复制]【英文标题】:How can I force Python to create a new variable / new scope inside a loop? [duplicate] 【发布时间】:2012-07-07 03:48:40 【问题描述】:今天我探索了 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
3
但我希望它打印出来
1
2
3
我为自己解释了这种行为,var
始终是同一个局部变量(并且 python 不会像其他语言那样创建一个新变量)。如何修复上面的代码,让每个闭包都返回另一个值?
【问题讨论】:
提示:什么在 Python 中引入了新的变量作用域? 刚刚看到***.com/questions/7546285/… 是一个重复的问题。我该如何关闭这个或者我应该删除它? @tampis:投票结束吧——版主最终会决定这个问题是合并还是删除。 实际上,我认为这甚至不会像您认为的那样。尝试在第一个循环之后添加del var
。
@cha0site del var
给出异常lobal name 'var' is not defined
【参考方案1】:
您不能在循环内的局部范围内创建新变量。无论您选择什么名称,您的函数将始终是该名称的闭包并使用其最新值。
解决这个问题的最简单方法是使用关键字参数:
closures = []
for x in [1, 2, 3]:
closures.append(lambda var=x: var)
【讨论】:
感谢您的编辑,现在可以 +1。【参考方案2】:最简单的方法是为你的 lambda 使用默认参数,这样x
的当前值被绑定为函数的默认参数,而不是在包含范围内查找 var
每次通话:
closures = []
for x in [1, 2, 3]:
closures.append(lambda var=x: var)
for c in closures:
print(c())
您也可以创建一个闭包(您拥有的不是闭包,因为每个函数都是在全局范围内创建的):
make_closure = lambda var: lambda: var
closures = []
for x in [1, 2, 3]:
closures.append(make_closure(x))
for c in closures:
print(c())
make_closure()
也可以这样写,这样可能会更易读:
def make_closure(var):
return lambda: var
【讨论】:
【参考方案3】:在您的示例中,var
始终绑定到循环的最后一个值。您需要使用 closures.append(lambda var=var: var)
将其绑定到 lambda 中。
【讨论】:
以上是关于如何强制 Python 在循环内创建新变量/新范围? [复制]的主要内容,如果未能解决你的问题,请参考以下文章