兼容Python2/3:except块无异常链抛异常 规避多余traceback
兼容实现方案
该方案无需依赖第三方模块,同时兼容Python 2.7与Python 3.3+(当前主流Py3版本均满足),完全符合输出要求。
如果需要严格对齐原代码的栈帧行号,可使用以下紧凑写法:
try: 1/0 except ZeroDivisionError: e = Exception("Error!"); e.__suppress_context__ = True; raise e
如果无需严格对齐栈帧行号,可拆分为多行编写,可读性更高:
try: 1/0 except ZeroDivisionError: e = Exception("Error!") e.__suppress_context__ = True raise e
方案说明
- 之前使用
six.raise_from产生额外栈帧的原因是,该方法是封装的外部函数,其内部的抛出逻辑会被记录到回溯栈中。本方案全程在当前except作用域内完成异常构造、属性设置与抛出,不会引入任何外部栈帧。 - Python 3环境下:手动将异常实例的
__suppress_context__属性设为True,可以强制抑制默认的隐式异常上下文,不会输出之前的ZeroDivisionError信息与During handling提示。 - Python 2.7环境下:给异常实例动态添加
__suppress_context__属性无任何副作用,与原生raise Exception("Error!")的执行逻辑、输出完全一致。
备注:Python 3.0-3.2版本无
__suppress_context__属性,且已停止维护多年,当前几乎无使用场景。若需兼容这些版本,可在except块外保存异常实例后再抛出,但会改变栈帧的行号,通常不建议。
输出效果
两种写法在Python 2.7与Python 3环境下的输出均符合预期:
Traceback (most recent call last): File "<stdin>", line 4, in <module> Exception: Error!
(注:多行写法的栈帧行号为raise e所在行,其余输出完全一致)
内容的提问来源于stack exchange,提问作者Bri Bri
相关产品推荐
相关产品推荐

