Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何强制Python在循环中创建新变量/新范围?_Python_Variables_For Loop_Parameters_Closures - Fatal编程技术网

如何强制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

今天我探索了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不像其他语言那样创建新的局部变量)。如何修复上述代码,使每个闭包返回另一个值?

您不能在循环的局部范围内创建新变量。无论选择什么名称,函数都将始终是该名称的闭包,并使用其最新值

最简单的方法是使用关键字参数:

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
。@cha0site
del-var
出现异常
未定义全局名称“var”
感谢您的编辑,现在+1就可以了。
def make_closure(var):
    return lambda: var