tru*_*nka 13 python name-binding
需要帮助理解PEP 227和Python语言参考中的以下句子
如果在封闭范围中引用变量,则删除名称是错误的.编译器将为'del name'引发一个SyntaxError.
缺少示例导致我无法在编译时重现错误,因此非常需要使用示例进行解释.
Mar*_*ers 17
以下提出了这个例子:
def foo():
spam = 'eggs'
def bar():
print spam
del spam
Run Code Online (Sandbox Code Playgroud)
因为该spam变量正在封闭范围内使用bar:
>>> def foo():
... spam = 'eggs'
... def bar():
... print spam
... del spam
...
SyntaxError: can not delete variable 'spam' referenced in nested scope
Run Code Online (Sandbox Code Playgroud)
Python检测到spam正在引用bar但未向该变量分配任何内容,因此它在周围的范围内查找foo.它被分配在那里,使del spam语句出现语法错误.
Python 3.2中删除了此限制; 您现在负责不自行删除嵌套变量; 你会得到一个运行时错误(NameError):
>>> def foo():
... spam = 'eggs'
... def bar():
... print(spam)
... del spam
... bar()
...
>>> foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in foo
File "<stdin>", line 4, in bar
NameError: free variable 'spam' referenced before assignment in enclosing scope
Run Code Online (Sandbox Code Playgroud)
一个例子可以是这样的:
>>> def outer():
... x = 0
... y = (x for i in range(10))
... del x
...
SyntaxError: can not delete variable 'x' referenced in nested scope
Run Code Online (Sandbox Code Playgroud)
基本上,这意味着您无法删除内部块(在这种情况下为genexp)中使用的变量。
请注意,这适用于python <= 2.7.x和python <3.2。在python3.2中,它不会引发语法错误:
>>> def outer():
... x = 0
... y = (x for i in range(10))
... del x
...
>>>
Run Code Online (Sandbox Code Playgroud)
请参阅此链接以了解更改的整个过程。
我认为python3.2语义更正确,因为如果您在函数外编写相同的代码,则它会起作用:
#python2.7
>>> x = 0
>>> y = (x for i in range(10))
>>> del x
>>> y.next() #this is what I'd expect: NameError at Runtime
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <genexpr>
NameError: global name 'x' is not defined
Run Code Online (Sandbox Code Playgroud)
将相同的代码放入函数中时,不仅会更改异常,而且错误也会在编译时发生。
| 归档时间: |
|
| 查看次数: |
3534 次 |
| 最近记录: |