为什么这两个“ x”引用不同的变量?


问题内容

在此代码中,lambda中的x表示for语句中的x。因此y[0]()返回2:

x = 0
y = [lambda : x for x in range(3)]
y[0]()

但是在此代码中,lambda中的x表示全局x,因此x[0]()返回全局x本身:

x = [lambda : x for x in range(3)]
x[0]()

我想知道为什么lambda中的x在第一段代码中引用本地x,而在第二段代码中引用全局x。


问题答案:

x``x在这两段代码中均指代全局。事实上,没有什么 ,但 一个全球性x的代码两件。这里没有局部变量,只有全局变量。

在第一个示例中,全局值为x2,因为它是列表推导分配给它的最后一个值。列表推导将其变量泄漏到@wim描述的封闭范围内。由于此处的封闭作用域是全局作用域,因此该变量x将泄漏到全局作用域中,并覆盖您之前设置的值0。

在第二个示例中,您创建了列表推导,但是将其值分配给(全局)变量x。这将覆盖x中已有的内容,因此全局变量x的值现在是列表。

在这两种情况下,当您调用列表中的一个函数(任何一个!)时,它都会返回的 当前x。您可以在这里看到:

>>> y = [lambda : x for x in range(3)]
>>> y[0]()
2
>>> x = 88
>>> y[0]()
88
>>> x = [lambda : x for x in range(3)]
>>> y = x
>>> y[0]()
[<function <lambda> at 0x017789B0>,
 <function <lambda> at 0x01828DB0>,
 <function <lambda> at 0x01828F30>]
>>> x = 88
>>> y[0]()
88