如何在Python 3.2程序中优雅地从None异常语法中包含Python 3.3? [英] How do I gracefully include Python 3.3 from None exception syntax in a Python 3.2 program?

查看:185
本文介绍了如何在Python 3.2程序中优雅地从None异常语法中包含Python 3.3?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to re-raise an exception to give the user better information about the actual error. Python 3.3 includes PEP 409. It adds the raise NewException from None syntax to suppress the context of the original exception.

但是,我的目标是Python 3.2。 Python脚本将进行解析,但是在运行时,如果遇到无脚本中的 语法,则会产生 TypeError:异常原因必须源自BaseException 。例如:

However, I am targeting Python 3.2. The Python script will parse, but at runtime if it encounters the from None syntax it will produce TypeError: exception causes must derive from BaseException. For example:

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从None封装在中try 只会产生更大的异常stacktrace。版本检查也不起作用,因为我在Xubuntu 12.10上的 python3.3 / usr / lib / python3 / dist-packages /中提取模块* 是为python3.2模块设置的。 (在sys.excepthook中会出现一个方便的错误:,它会创建大量追溯。)

Encapsulating raise e_reraise from None in a try just produces an even larger exception stacktrace. A version check doesn't work either, since my python3.3 on Xubuntu 12.10 pulls modules from /usr/lib/python3/dist-packages/* which was is setup for python3.2 modules. (You get a convenient Error in sys.excepthook: which creates a massive traceback.)

在Python 3.3中运行时,有没有办法使用PEP 409功能,而在Python 3.2中却无视它呢?

Is there a way to use the PEP 409 feature when running in Python 3.3, while silently ignoring it in Python 3.2?

推荐答案

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

The PEP you linked provides the solution:



  • raise NewException()从无

  • raise NewException() from None

遵循明确声明原始
异常的现有语法

Follows existing syntax of explicitly declaring the originating exception


  • exc = NewException();不包括__context__ =无;提高例外

  • exc = NewException(); exc.__context__ = None; raise exc

以前方法的非常详细的方式

Very verbose way of the previous method

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

So, you simply have to avoid the new syntax and use the verbose equivalent.

如果您不想查看可以将代码放入函数中的赋值:

If you don't want to see the assignments you can put the code into a function:

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

然后执行:

raise suppress_context(TheErrorClass())

编辑:,如Martijn PEP 415 所指出更改了此行为:

as pointed out by Martijn PEP 415 changed this behaviour:


总而言之,从原因中获得收益等同于:

exc.__cause__ = cause
raise exc


这样,而不是将 __ context __ 设置为 None 您应将 __ cause __ 设置为 None

Thus, instead of setting __context__ to None you should set __cause__ to None.

如果您真的想使用新语法,那么唯一的方法是将 sys.excepthook 替换为解析回溯输出并删除部分的内容你不想要的但是在这种情况下,您也必须 执行以下操作:

If you really want to use the new syntax, then the only way to do this is to replace sys.excepthook with something that parses the traceback output and removes the the parts that you don't want. But in this case you also must do this:

try:
    raise error from None
except TypeError:
    raise error

然后 excepthook 应该搜索回溯,是否应该从None 行中删除与 raise错误相关的部分。这不是一个简单的任务,与其他解决方案相比,您得到的代码更多。

Then the excepthook should search the traceback and if it should remove the parts related to the raise error from None line. Not a simple task and you end up with more code than the other solution.

这篇关于如何在Python 3.2程序中优雅地从None异常语法中包含Python 3.3?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆