我会以您正在考虑的类似方式执行此操作,使用“您不应通过” Gandalf异常处理程序except Exception
来捕获所有非系统退出异常set
,同时创建应通过并结束的异常的黑名单重新-提高。
如果调用堆栈中没有更高的处理程序,则使用Gandalf 处理程序将确保GeneratorExit
和(所有系统退出异常)通过并终止程序。在这里,您可以检查捕获的异常中的 a是否确实属于列入黑名单的异常集合,然后重新检查。SystemExit
KeyboardInterrupt
type(e)
__class__
e
raise
作为一个小示范:
import exceptions # Py2.x only
# dictionary holding {exception_name: exception_class}
excptDict = vars(exceptions)
exceptionNames = ['MemoryError', 'OSError', 'SystemError'] # and others
# set containing black-listed exceptions
blackSet = {excptDict[exception] for exception in exceptionNames}
现在保存我们不想blackSet = {OSError, SystemError, MemoryError}
处理的非系统退出异常的类。
块现在try-except
看起来像这样:
try:
# calls that raise exceptions:
except Exception as e:
if type(e) in blackSet: raise e # re-raise
# else just handle it
使用捕获所有异常的示例BaseException
可以帮助说明我的意思。(这样做仅用于演示目的,以便了解这种提升将如何最终终止您的程序)。请注意:我不建议您使用BaseException
; 我使用它是为了演示什么异常实际上会“通过”并导致终止(即BaseException
捕获的所有内容):
for i, j in excptDict.iteritems():
if i.startswith('__'): continue # __doc__ and other dunders
try:
try:
raise j
except Exception as ex:
# print "Handler 'Exception' caught " + str(i)
if type(ex) in blackSet:
raise ex
except BaseException:
print "Handler 'BaseException' caught " + str(i)
# prints exceptions that would cause the system to exit
Handler 'BaseException' caught GeneratorExit
Handler 'BaseException' caught OSError
Handler 'BaseException' caught SystemExit
Handler 'BaseException' caught SystemError
Handler 'BaseException' caught KeyboardInterrupt
Handler 'BaseException' caught MemoryError
Handler 'BaseException' caught BaseException
最后,为了使这个 Python 2/3 不可知,您可以try
并且import exceptions
如果失败(在 Python 3 中就是这样),则回退到builtins
包含 all的导入Exceptions
;我们按名称搜索字典,所以没有区别:
try:
import exceptions
excDict = vars(exceptions)
except ImportError:
import builtins
excDict = vars(builtins)
我不知道是否有更聪明的方法来实际执行此操作,另一种解决方案可能不是使用try-except
带有 signle的 a ,而是except
拥有 2 个处理程序,一个用于黑名单异常,另一个用于一般情况:
try:
# calls that raise exceptions:
except tuple(blackSet) as be: # Must go first, of course.
raise be
except Exception as e:
# handle the rest