Python变量命名/绑定混淆

9 投票
2 回答
795 浏览
提问于 2025-04-17 18:42

我刚开始学习Python开发,在阅读语言文档时,看到了一句话:

在一个外部作用域中被引用的名字是不能解除绑定的;编译器会报SyntaxError错误。

为了理解这个错误,我在交互式命令行中尝试去制造这个错误,但一直没能成功。我使用的是Python 2.7.3,所以不能使用nonlocal这个关键词,像这样:

def outer():
  a=5
  def inner():
     nonlocal a
     print(a)
     del a

在没有使用nonlocal的情况下,当Python在inner函数中看到del a时,它会把它当作一个没有绑定的局部变量,从而抛出UnboundLocalError异常。

显然,对于全局变量,这条规则有例外。那么我该如何制造一个情况,让我“非法”解除一个在外部作用域中被引用的变量名呢?

2 个回答

5

要引发那个错误,你需要在外部作用域中解除对变量的绑定。

>>> def outer():
...  a=5
...  del a
...  def inner():  
...   print a
... 
SyntaxError: can not delete variable 'a' referenced in nested scope
10

删除操作必须在外部作用域进行:

>>> def foo():
...     a = 5
...     def bar():
...         return a
...     del a
... 
SyntaxError: can not delete variable 'a' referenced in nested scope

在Python 3中,编译时的限制已经被取消:

$ python3.3
Python 3.3.0 (default, Sep 29 2012, 08:16:08) 
[GCC 4.2.1 Compatible Apple Clang 3.1 (tags/Apple/clang-318.0.58)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def foo():
...     a = 5
...     def bar():
...         return a
...     del a
...     return bar
... 
>>>

相反,当你试图引用a时,会抛出一个NameError错误:

>>> foo()()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in bar
NameError: free variable 'a' referenced before assignment in enclosing scope

我有点想在这里提交一个文档错误。对于Python 2,文档的说明有点误导;实际上,是在嵌套作用域中删除一个变量才会引发编译时错误,而在Python 3中,这个错误根本不会再出现。

撰写回答