我会以与您想的类似的方式执行此操作,在创建一个应通过并重新引发的异常将set 列入黑名单。
使用 Gandalf 处理程序 将确保 GeneratorExit、SystemExit 和 KeyboardInterrupt(所有系统退出异常)通过并在调用中没有其他处理程序存在时终止程序堆。在这里您可以使用type(e) 检查捕获的异常e 的__class__ 实际上属于列入黑名单的异常集合,然后重新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 987654350@;我们按名称搜索字典,所以没有区别:
try:
import exceptions
excDict = vars(exceptions)
except ImportError:
import builtins
excDict = vars(builtins)
我不知道是否有更聪明的方法来实际执行此操作,另一种解决方案可能不是使用带有信号 except 的 try-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