Python变量命名/绑定困惑

9

我是一个相对新手的Python开发者,在阅读语言文档时,我看到了一行代码:

解除绑定外围范围引用的变量名是不合法的;编译器会报告SyntaxError。

所以在学习的过程中,我试图在交互式shell中创建这个错误,但我还没有找到方法。我正在使用Python v2.7.3,因此像nonlocal这样的关键字并不能成功。

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

如果不使用 nonlocal,那么在内部函数中出现 del a 的时候,Python 会将其解释为未绑定的本地变量,并抛出一个 UnboundLocalError 异常。显然,全局变量有一个例外,那么如何创建一种情况,在这种情况下我“非法”取消绑定了一个被封闭作用域引用的变量名呢?

2个回答

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中则不再引发该错误。


好的,现在更清楚了,谢谢。同意关于 Python 2 文档在这方面存在误导性的说法。在我看来,“由封闭作用域引用的名称”似乎暗示了一个变量,在你取消绑定该名称的作用域之外的作用域中被引用。 - Default

5

要触发该错误,您需要在外部作用域的上下文中取消绑定变量。

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

1
非常感谢,显然文档有点误导。这样更有意义。 - Default

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接