Python 怎么是'x=42;x=lambda:x`已解析?
我感到惊讶的是,这一断言失败了:Python 怎么是'x=42;x=lambda:x`已解析?,python,language-lawyer,Python,Language Lawyer,我感到惊讶的是,这一断言失败了: x = 42 x = lambda: x assert x() == 42 似乎x最终递归地引用自身,因此x(),x()()等都是函数 什么是用来解析的规则,在哪里有文档记录 顺便说一句(上述情况并非意外),在lambda定义之后,x的原始值没有任何引用: class X: def __del__(self): print('deleting') x = X() x = lambda: x # 'deleting' is printed here 第
x = 42
x = lambda: x
assert x() == 42
似乎x
最终递归地引用自身,因此x()
,x()()
等都是函数
什么是用来解析的规则,在哪里有文档记录
顺便说一句(上述情况并非意外),在lambda定义之后,x
的原始值没有任何引用:
class X:
def __del__(self): print('deleting')
x = X()
x = lambda: x # 'deleting' is printed here
第一个任务是无关的;
lambda
主体中的x
为:
这与以下原因相同,也用于:
lambda是一个匿名函数对象。Python将等式右侧的内容完全解析为单个匿名对象,然后解析左侧的内容进行赋值
x = lambda: x
首先将lambda:x
编译成一个函数对象,该函数对象返回调用时x
中发生的任何内容。然后它用这个函数对象重新绑定x
,删除之前出现的任何对象
现在,x
是一个返回x
中任何内容的函数。。。这是一个函数,它返回x
中的任何内容,等等。。。因此,您可以根据需要多次编写x()
,并且仍然可以获得原始lambda:x
函数对象
Python函数有一个本地名称空间,但只有在函数中分配的变量驻留在那里。由于x
未在lambda
中分配,因此它在包含范围内解析-即模块级别“x”。一段相同的代码是
def x():
return x
将此与
def x():
x = 1
return x
现在,参数
x
是一个局部变量,与全局x
无关。变量x
由第一个赋值创建,并与第二个赋值一起反弹
x = lambda: x
由于lambda中的x
在调用lambda之前不会计算,因此调用它将计算到最近分配的值
请注意,这不是动态范围-如果它是动态的,那么下面将打印“99”,但它打印“它就像
def x():返回x
。因此这是词法(=静态)范围,正确吗?也相关:。是的,这是正确的。注意:如果使用非局部x;x=99,它会打印99。或者使用测试(lambda:x)
,将42与99区分开来,该示例更容易理解
def x():
x = 1
return x
x = 42
x = lambda: x
def test(f):
x = 99
print(f())
test(x)