发生未处理的异常时如何跳过sys.exitfunc

时间:2020-03-05 18:58:15  来源:igfitidea点击:

如我们所见,即使程序应该死了,它也会从坟墓里说话。如果发生异常,是否可以"注销"退出功能?

import atexit

def helloworld():
    print("Hello World!")

atexit.register(helloworld)

raise Exception("Good bye cruel world!")

输出

Traceback (most recent call last):
  File "test.py", line 8, in <module>
    raise Exception("Good bye cruel world!")
Exception: Good bye cruel world!
Hello World!

解决方案

回答

如果你打电话

import os
os._exit(0)

退出处理程序将不会被我们调用,也不会被应用程序中其他模块注册的那些调用。

回答

我真的不知道为什么要这样做,但是我们可以安装一个异常钩子,只要引发未捕获的异常,Python就会调用该异常钩子,并清除atexit模块中已注册函数的数组。

像这样的东西:

import sys
import atexit

def clear_atexit_excepthook(exctype, value, traceback):
    atexit._exithandlers[:] = []
    sys.__excepthook__(exctype, value, traceback)

def helloworld():
    print "Hello world!"

sys.excepthook = clear_atexit_excepthook
atexit.register(helloworld)

raise Exception("Good bye cruel world!")

请注意,如果从" atexit"注册的函数引发异常,它的行为可能会不正确(但是,即使不使用此钩子,该行为也会很奇怪)。

回答

除了调用os._exit()以避免注册的退出处理程序外,我们还需要捕获未处理的异常:

import atexit
import os

def helloworld():
    print "Hello World!"

atexit.register(helloworld)    

try:
    raise Exception("Good bye cruel world!")

except Exception, e:
    print 'caught unhandled exception', str(e)

    os._exit(1)