这些天我正在深入学习Python的异常处理功能。我遇到了exception SystemExit
。在从official Python Docs阅读此内容时,我心里明白,当我通过按 Ctrl + c 来终止Python脚本时会发生什么?
让我们看看这个示例代码:
def func1(a,b):
print "func1: "+str(a/b)
#some more functions
def func2(a,b):
print "func2: "+str(a/b)
#some more functions
if __name__=="__main__":
import random
count=0
for i in range(1000000):
count=count+1
print "count: "+str(count)
try:
func1(random.randint(-2,3),random.randint(-2,3))
except KeyboardInterrupt:
raise
except:
print "error in func1"
try:
func2(random.randint(-2,3),random.randint(-2,3))
except KeyboardInterrupt:
raise
except:
print "error in func2"
print "\n"
在此示例代码中,我正在捕捉KeyboardInterrupt
,因此我可以通过按 Ctrl + c 来停止我的脚本。我是否应该抓住SystemExit
来使这段代码更加成熟?如果是,那么为什么?实际上这个问题是我在标题上出现的主要问题的来源。所以不要认为我在一篇文章中提出两个不同的问题。
答案 0 :(得分:4)
您通常无需捕捉SystemExit
因为exit()
和sys.exit()
功能正常运作的原因:
<强> sys.exit([参数])强>
退出Python。这是通过引发
SystemExit
异常来实现的,因此finally
语句的try
子句指定的清理操作得到遵守,并且可以拦截外层的退出尝试。
示例:
try:
exit()
except SystemExit:
print "caught"
因此,您通常不希望首先捕获所有异常(通过使用空except:
子句)。最好的方法通常是使您的异常处理程序尽可能具体。否则,它会使您的应用程序调试异常困难,因为它要么完全隐藏错误,要么至少使得难以诊断细节。
答案 1 :(得分:1)
你的函数可以引发的唯一例外是ZeroDivisionError
,所以你应该只抓住那个:
import random
if __name__ == "__main__":
for count in range(1000000):
print "count:", count
try:
func1(random.randint(-2, 3),random.randint(-2, 3))
except ZeroDivisionError:
print "error in func1"
try:
func2(random.randint(-2, 3),random.randint(-2, 3))
except ZeroDivisionError:
print "error in func2"
print "\n"
答案 2 :(得分:1)
你的标题与你问题的主体有所不同。
标题:
内部发生的事情是python捕获SIGINT
并从中引发KeyboardInterrupt
异常。
文字:
您不想except:
。
相反,你想要
if __name__=="__main__":
try:
import random
count=0
for i in range(1000000):
count=count+1
print "count: "+str(count)
try:
func1(random.randint(-2,3),random.randint(-2,3))
except Exception, e:
print "error in func1", e # or something...
try:
func2(random.randint(-2,3),random.randint(-2,3))
except Exception, e:
print "error in func2", e # or something...
print "\n"
except Exception:
raise # any other "normal" exception.
except: # Here it is ok, as you handle most exceptions above.
pass
通常应该处理的大多数“正常”异常来自Exception
。那些具有内在意义且通常不应被捕获的(全球范围除外)不会derive from Exception
。
这些是KeyboardInterrupt
,SystemExit
和GeneratorExit
。
答案 3 :(得分:1)
如果你不确定你所调用的代码是什么异常会引发错误,那么你应该(按照优先顺序):
Exception
,而非一切。 KeyboardInterrupt
和SystemExit
都不是Exception
的子类,但用于指示错误的所有标准Python异常都是。