我已阅读以下帖子,但我仍然不确定。
Why python compile the source to bytecode before interpreting?
如果我有一个包含以下代码的Python文件myfunctions.py。
x = 3
def f():
print x
x = 2
然后,说$ python myfunctions.py
完全正常。
但是现在对上面的文件做一个小改动。新文件如下所示。
x = 3
def f():
print x
x = 2
f() # there is a function call now
这一次,代码发出错误。现在,我试图理解这种行为。到目前为止,这些是我的结论。
x=3
有人可以对此发表评论吗?提前致谢。对不起,如果以前已经解决了这个问题。
答案 0 :(得分:2)
当解释器读取函数时,对于它遇到的每个“名称”(变量),解释器决定该名称是 local 还是非本地。使用的标准非常简单......在正文的任何地方是否有一个赋值语句(禁止global
语句)? e.g:
def foo():
x = 3 # interpreter will tag `x` as a local variable since we assign to it here.
如果该名称有赋值语句,则该名称将标记为“local”,否则将标记为非本地名称。
现在,在您的情况下,您尝试打印标记为本地的变量,但是在实际到达关键赋值语句之前执行此操作。 Python查找本地名称,但找不到它,因此它会引发UnboundLocalError
。
Python是非常动态的,允许你做很多疯狂的事情,这是使它如此强大的一部分。这样做的缺点是,除非你实际上运行函数,否则检查这些错误变得非常困难 - 实际上,python已决定不检查其他任何错误比函数运行之前的语法。这解释了为什么在实际调用函数之前,你永远不会看到异常。
如果希望python将变量标记为全局变量,则可以使用显式global
1 语句来执行此操作:
x = 3
def foo():
global x
print x
x = 2
foo() # prints 3
print x # prints 2
1 python3.x进一步采用了这个概念,介绍了nonlocal
关键字
答案 1 :(得分:1)
另一半是Python不会在函数(或函数对象)中查找错误,而不是执行错误。因此,在第一种情况下,由于未调用f()
,因此不会检查操作顺序错误。
在这方面,它不像C和C ++,它要求所有内容都在前面完全声明。它有点像C ++模板,在实际实例化代码之前,可能无法找到模板代码中的错误。