为什么我能捕获由eval代码引发的SyntaxError(或IndentationError或TabError),但无法捕获源代码本身引起的错误?
考虑这两个代码片段:
try:
a+a=a
except SyntaxError:
print "first exception caught"
.
try:
eval("a+a=a")
except SyntaxError:
print "second exception caught"
在第二种情况下,“第二个异常...”的语句被打印出来了(异常被捕获),而在第一种情况下则没有。
第一个异常(我们称它为“语法错误1”)和第二个异常(“语法错误2”)有什么不同吗?
有没有办法捕获语法错误1(从而抑制编译时的错误)?把大块代码放在eval
里并不是个好办法;)
2 个回答
5
简短回答:不可以。
语法错误是在代码被解析的时候发生的,对于普通的Python代码来说,这个解析是在代码执行之前进行的——也就是说,代码并没有在try/except块里面执行,因为根本就没有执行。
不过,如果你使用eval或者exec来运行一些代码,那么这个代码是在运行时被解析的,这样你就可以捕捉到异常了。
26
在第一种情况下,异常是由编译器引发的,而编译器是在 try/except
结构还不存在的时候就已经在运行了(因为编译器会在解析代码后立即设置这个结构)。在第二种情况下,编译器运行了两次——异常是在编译器作为 eval
的一部分运行时引发的,这时 try/except
结构已经在第一次编译器运行后设置好了。
所以,要捕捉语法错误,无论如何,你必须让编译器运行两次——eval
是一种方法,显式调用 compile
内置函数是另一种方法,import
也很方便(在把代码写到另一个文件后),exec
和 execfile
也是其他可能的选择。但无论你用什么方法,语法错误只能在编译器第一次运行后,设置好你需要的 try/except
块之后才能被捕捉到!