我得到了Python执行的意外行为。
if True:
print("Hello")
else:
I am an error. what can you do about it?
现在,此代码不会引起语法,因为控件永远不会进入其他语句。在诸如C 之类的编译语言中,它会出现错误。即使在Java中,未使用的代码也是一个错误。但不在python中。
现在在这种情况下:
x = 10
def foo():
print(x)
x += 1
按照此处指定的打印语句提出了一个Unboundlocalerror。根据以前的逻辑,此错误不应在控件遇到x = 1之前。但这确实像其他任何编译的语言一样。
那么如何确定代码何时按编译或解释运行?
编辑:如果将其编译到bytecode.pyc文件中,然后解释。那为什么未检测到第一个示例的else语句?
相反。执行之前,Python将源编译为字节代码。第一种情况将在汇编阶段引起语法误差。
在第二种情况下,编译器看到x
在函数中修改了,因此它将x
绑定到函数对象。每次调用函数时,都会创建函数名称空间,但仅在分配变量时才会出现该变量。只有当您执行print(x)
时,Python才意识到您要求您提供尚未分配的局部变量。当并非所有执行路径都像应有的那样设置变量时,这是一个常见的错误。
稍微修改了示例,有时设置了局部变量,而有时则不是。设置时,您会看到当地人中的变量,并且打印起作用。当未设置时,变量不在当地人中,打印失败。
x = 10
def foo(val):
if val:
x = 1
print(val, 'before', locals())
print(x)
print(val, 'after')
x += 1
foo(True)
foo(False)
输出
True before {'val': True, 'x': 1}
1
True after
False before {'val': False}
Traceback (most recent call last):
File "o.py", line 11, in <module>
foo(False)
File "o.py", line 6, in foo
print(x)
UnboundLocalError: local variable 'x' referenced before assignment
它总是按解释运行;但是语法检查器在整个文件上被调用为第一步,该步骤生成字节码文件。
在Python 2.7和3.5中,您放在顶部的代码将导致语法错误:
python3 junk.py
File "junk.py", line 4
I am an error. what can you do about it?
^
SyntaxError: invalid syntax
不可能在Python中获得"运行时"语法错误;实现这一目标的唯一方法是动态导入具有语法错误的模块。
我不确定我已经理解了您的问题,但是第二种情况下的错误是运行时错误;就像在C中进行int x = 0; y = 10/x;
一样;可变范围("目前存在X?")在Python的语法解析期间无法解决。
-
编辑;这是我终端的转储:
Clank:tmp doug$ cat junk.py
if True:
print("Hello")
else:
I am an error. what can you do about it?
Clank:tmp doug$ python junk.py
File "junk.py", line 4
I am an error. what can you do about it?
^
SyntaxError: invalid syntax
Clank:tmp doug$ python3 junk.py
File "junk.py", line 4
I am an error. what can you do about it?
^
SyntaxError: invalid syntax
可以在阅读道格(Doug and Jim)的答案后,我想我对这是如何工作的想法。首先在repl(ipython,默认)中起作用的所有示例
文件:如果您将其写在文件中:
if True:
print("Hi")
else:
I am an error. What can you do about it?
运行文件,它将抛出语法。这证明,每当我们从文件中执行Python代码时,它都会生成一个字节码,并且由于该语句否则不是有效的Python表达式,我们都会获得SyntaxError。
repl :随着替补,事情变得有些依赖。如果您键入
,请在Python解释器中>>>def foo():
if True:
print("Hey")
else:
I am an error. What can you do about it?
>>>foo()
Hey
成功的执行意味着没有字节代码对吗?保持。
如果写这篇文章:
>>>x = 10
>>>def foo():
print(x)
x += 1
>>>foo()
和繁荣!一切都崩溃了,您会在打印(x)语句中获得Unboundlocalerror。这意味着bytecode在那里。
那么,这里到底发生了什么?
如果Python发现了一个变量的一次单一出现,则首先要通过阅读所有内容来优化其工作。因此,在第二个示例中,当代码遇到打印(x)时,它试图在x上查找所有操作。很快,它找到了语句x = 1。由于本地范围中没有提及X,而Python永远不会在全局范围中寻找变量,如果未明确提及,我们有
UnboundLocalError: local variable 'x' is referenced before assignment
结论性证明
如果我们写这样的东西:
>>>x = 10
>>>def foo():
if True:
print(x)
else:
x+=1
>>>foo()
UnboundLocalError: local variable 'x' referenced before assignment
就是这样!
x = 1永远不会被执行,但是由于打印语句打印x,另一个引用(x = 1)是问题,因此在打印值之前遇到了错误。第一种情况在没有SyntaxError的情况下正常工作,因为它从来没有打扰过其他陈述,因为它从来没有关系。
如果您是通过一些短(而不是pythons默认depp)的交互式来运行的,则可能会使此操作实际执行,而没有错误( IPython
s'qtconsole允许它w/o w/o例如)。为什么允许这样做仅取决于替代及其实现。
在Python中,此 a SyntaxError
;它不能生成任何字节:
s ="""
i= 1
if i:
print("Hello")
else:
I am an error. what can you do about it?
"""
c = compile(s, '', mode='exec')
File "<string>", line 6
I am an error. what can you do about it?
^
SyntaxError: invalid syntax
语法不允许, string文字被允许放置在它们之间的空间( python后来的concatenates ),名称不是(当然,单个名称本身就是允许的)。简而言之,这在解析阶段失败:
from parser import suite
st = suite(s)
File "<string>", line 6
I am an error. what can you do about it?
^
SyntaxError: invalid syntax
python不知道看到两个名称被一个空间隔开时该怎么办,空间并不意味着任何操作(str
文字除外)。