`del` 语句和自由变量

`del` statement and free variables

今天测试了一些 Python 代码,我尝试了以下代码:

(以下在 Python 3.2+ 上运行,尽管以前的版本会在使用 del 并且在封闭范围内引用变量时引发 SyntaxError

def x():
    N = 200
    def y():
            print(N)
    del N
    y()
x() 
NameError: free variable 'N' referenced before assignment in enclosing scope 

如您所见,Python 不会引发 NameError: global name 'N' is not defined,这让我想知道一件事:

when del 语句与函数的封闭范围一起使用,以删除嵌套函数内部使用的自由变量,例如 y 函数,如果在我们的例子中是自由变量 N 是通过封闭范围中的 del 语句删除的,del 实际上所做的是删除名称的 (N) 值并将其绑定到封闭范围 ?

A) Is that why it raises: NameError: free variable 'N' referenced before assignment... rather than NameError: global name 'N' is not defined?

B) How does del actually delete a name? Does it unbind its value and keep it in a scope ?

我发现了一个类似的案例here

它是这样工作的:当你在y里面写print(N)但是不赋值给y里面的N,这意味着当时[=11] =] 被定义时,Python 会在其封闭范围中查找最近的一个名称 N 被分配的范围。 N 的赋值发生在 y 的定义之前还是之后,或者稍后是否用 del 撤消都没有关系;它只是寻找最近的封闭范围,其中存在对 N 的分配。在这种情况下,由于 N 是在 x 内部分配的,因此 y 本质上做了一个小注释说 "when I need to get N, I will look in the scope of x".

所以当你实际调用 y 时,它会在 x 的范围内查找 N。如果它不存在,则会出现错误。请注意,如果在调用 y.

之后移动 N = 100 行,则在没有 del 的情况下也会出现同样的错误