【问题标题】:How to imitate Python 3's raise ... from in Python 2?如何从 Python 2 中模仿 Python 3 的 raise ...?
【发布时间】:2015-02-03 18:24:36
【问题描述】:

Python 3 很简洁

try:
    raise OneException('sorry')
except OneException as e:
    # after a failed attempt of mitigation:
    raise AnotherException('I give up') from e

允许在不丢失上下文的情况下引发后续异常的语法。在 Python 2 中我能想到的最好的类比是

raise AnotherException((e,'I give up')), None, sys.exc_info()[2]

(e,'') 是一个丑陋的黑客,将原始异常的名称包含在消息中。但是没有更好的方法吗?

【问题讨论】:

  • 您可以只使用raise 而不使用任何参数,但如果您这样做,我认为您不能将类型更改为AnotherException
  • @Kevin 我知道,这只是一个简化 - 在更现实的情况下,这就像一个文件未找到异常并且它的故障保护也失败了,因此产生了一个不同的异常以及其他一些消息好吧,但应该保留原来的异常
  • 我认为 Python 2 没有为这样的事情提供适当的支持。我想你可以用reraise() 函数或其他东西来包装你丑陋的黑客。鉴于release schedule for 2.8,您可能会考虑切换到 3.x。您有任何仅 2.x 的依赖项吗?
  • @Kevin hg.python.org/peps/rev/… :P 目前我使用 Python 2.7 的主要原因是 PythonXY (Windows),但我也是出于好奇而询问

标签: python-2.7 exception python-3.x traceback raise


【解决方案1】:

python-future 中有一个raise_from;只需安装它

pip install future

并导入使用

from future.utils import raise_from
# or: from six import raise_from

class FileDatabase:
    def __init__(self, filename):
        try:
            self.file = open(filename)
        except IOError as exc:
            raise_from(DatabaseError('failed to open'), exc)

更新

兼容包six 还支持raise_from,从1.9 版(2015 年发布)开始。它的使用方式与上述相同。

【讨论】:

  • 嗨。 six 中的 raise_from 实际上模仿了 python2 中的普通 raise(exec),所以它没有得到 python 3 的行为:(
  • 是的,raise_from in six 模仿普通的加注。但是同样来自sixreraise 工作了。请参阅此链接中的示例:python-future.org/compatible_idioms.html 或我建议的解决方案。
【解决方案2】:

请尝试使用 Six.reraise,而不是使用 Six.raise_from,如本页所述:

http://python-future.org/compatible_idioms.html

from six import reraise as raise_ 
# or from future.utils import raise_

traceback = sys.exc_info()[2]
raise_(ValueError, "dodgy value", traceback)

【讨论】:

    猜你喜欢
    • 2018-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-28
    • 1970-01-01
    • 2014-06-22
    • 2018-01-07
    • 2019-12-08
    相关资源
    最近更新 更多