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)