我正在尝试重新引发异常,以便为用户提供有关实际错误的更好信息。 Python 3.3 包括 PEP 409 。它添加了 raise NewException from None 语法来抑制原始异常的上下文。

但是,我的目标是 Python 3.2。 Python 脚本将解析,但在运行时如果遇到 from None 语法,它将生成 TypeError: exception causes must derive from BaseException 。例如:

try:
    regex_c = re.compile('^{}$'.format(regex))
except re.error as e:
    e_msg = 'Regular expression error in "{}"'.format(regex)
    e_reraise = Exception(e_msg)
    # Makes use of the new Python 3.3 exception syntax [from None]
    # to suppress the context of the original exception
    # Causes an additional TypeError exception in Python 3.2
    raise e_reraise from None

raise e_reraise from None 封装在 try 中只会产生更大的异常堆栈跟踪。版本检查也不起作用,因为我在 Xubuntu 12.10 上的 python3.3 从为 python3.2 模块设置的 /usr/lib/python3/dist-packages/* 中提取模块。 (你会得到一个方便的 Error in sys.excepthook:,它创建了一个 大规模的 回溯。)

有没有办法在 Python 3.3 中运行时使用 PEP 409 功能,而在 Python 3.2 中静默忽略它?

最佳答案

您链接的 PEP 提供了解决方案:



因此,您只需避免使用新语法并使用冗长的等效语法。

如果您不想看到分配,可以将代码放入函数中:

def suppress_context(exc):
    exc.__context__ = None
    return exc

然后做:
raise suppress_context(TheErrorClass())

编辑:Martijn PEP 415 指出的 改变了这种行为:



因此,与其将 __context__ 设置为 None ,不如将 __cause__ 设置为 None

如果你真的想使用新的语法,那么唯一的方法就是用解析回溯输出的东西替换 sys.excepthook 并删除你不想要的部分。但在这种情况下,您也必须这样做:
try:
    raise error from None
except TypeError:
    raise error

然后 excepthook 应该搜索回溯,如果它应该删除与 raise error from None 行相关的部分。这不是一项简单的任务,您最终会得到比其他解决方案更多的代码。

关于python - 如何在 Python 3.2 程序中从 None 异常语法优雅地包含 Python 3.3?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15123137/

10-16 12:07