Python 未绑定变量和名称

Python 未绑定变量和名称,python,variables,namespaces,Python,Variables,Namespaces,根据python参考手册我们有 如果根本找不到名称,将引发NameError异常。如果 该名称引用尚未绑定的局部变量,即 引发UnboundLocalError异常。UnboundLocalError是一个子类 名称错误 我不明白何时抛出UnboundLocalError?因为 Python缺少声明,允许进行名称绑定操作 代码块中的任意位置 那么,我们如何才能声明一个变量,而不是初始化它呢?您可以引用一个名称,而不必为其赋值: >>> foobar Traceback (mos

根据
python参考手册
我们有

如果根本找不到名称,将引发NameError异常。如果 该名称引用尚未绑定的局部变量,即 引发UnboundLocalError异常。UnboundLocalError是一个子类 名称错误

我不明白何时抛出
UnboundLocalError
?因为

Python缺少声明,允许进行名称绑定操作 代码块中的任意位置

那么,我们如何才能声明一个变量,而不是初始化它呢?

您可以引用一个名称,而不必为其赋值:

>>> foobar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'foobar' is not defined
因为
spam='eggs'
永远不会执行,
print spam
会引发
UnboudLocalError

请注意,Python中从未声明过任何名称。无论绑定与否,声明都不是语言的一部分

相反,绑定用于确定名称的范围;绑定操作包括赋值、用于
for
循环的
名称、函数参数、导入语句、保存
except
子句中捕获的异常的名称、带有
语句的
中上下文管理器的名称所有绑定名称

如果一个名称绑定在一个作用域中(例如在函数中),那么它就是一个本地名称,除非您使用
global
语句(或者Python 3中的
nonlocal
语句)来显式地将该名称标记为全局(或闭包)

因此,以下是一个错误:

>>> foo = None
>>> def bar():
...     if False:
...         foo = 'spam'
...     print foo
... 
>>> bar()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in bar
UnboundLocalError: local variable 'foo' referenced before assignment
因为现在Python编译器知道您希望
foo
成为一个全局对象


所有这些都记录在Python参考文档的中。

还有一个地方是当变量在全局范围内声明时,如果它在函数范围内使用,则应特别将其称为全局变量,否则将发生UnboundLocalError。以下是一个例子:

var = 123
def myfunc():
    var = var + 1
    print var

myfunc()
错误:

UnboundLocalError: local variable 'var' referenced before assignment

非常好的例子,谢谢!这是否意味着指定的块绑定是在该块的代码开始执行之前创建的?@dmitri:编译器将本地名称存储在代码块中;这使得字节码可以使用正确的操作码来加载全局名称、本地名称和闭包。Python在编译为字节码时决定变量是否为本地变量。如果它曾经被分配到,它是本地的(除非有
全局
非本地
声明);导入,函数参数,
用于
循环目标,
除外
with
子句
作为
目标所有绑定名称。您在技术上是正确的。。。最好的一种是正确的。(但在我看来,这些都是任务。)
var = 123
def myfunc():
    var = var + 1
    print var

myfunc()
UnboundLocalError: local variable 'var' referenced before assignment