【问题标题】:How can I force Python to create a new variable / new scope inside a loop? [duplicate]如何强制 Python 在循环内创建新变量/新范围? [复制]
【发布时间】: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 中引入了新的变量作用域?
  • 刚刚看到stackoverflow.com/questions/7546285/… 是一个重复的问题。我该如何关闭这个或者我应该删除它?
  • @tampis:投票结束吧——版主最终会决定这个问题是合并还是删除。
  • 实际上,我认为这甚至不会像您认为的那样。尝试在第一个循环之后添加del var
  • @cha0site del var 给出异常lobal name 'var' is not defined

标签: python variables for-loop parameters closures


【解决方案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 中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-30
      • 1970-01-01
      • 1970-01-01
      • 2015-06-25
      • 1970-01-01
      • 1970-01-01
      • 2011-02-13
      • 2022-01-05
      相关资源
      最近更新 更多