我正在编写一个模块,并希望为它可能引发的异常建立一个统一的异常层次结构(例如,从FooError
所有的抽象类foo
模块的特定例外)。这允许模块的用户捕获这些特定的异常并在需要时明确地处理它们。但是模块引发的许多异常是由于其他一些异常而引发的;例如由于文件上的 OSError 导致某些任务失败。
我需要的是“包装”捕获的异常,使其具有不同的类型和消息,以便通过任何捕获异常的方式在传播层次结构中进一步获取信息。但我不想丢失现有的类型、消息和堆栈跟踪;对于尝试调试问题的人来说,这都是有用的信息。顶级异常处理程序不好,因为我试图在异常进一步传播堆栈之前对其进行装饰,而顶级处理程序为时已晚。
通过派生我的模块部分解决了这个问题foo
现有类型的特定异常类型(例如class FooPermissionError(OSError, FooError)
),但这并没有使将现有异常实例包装在新类型中或修改消息变得更容易。
蟒蛇的PEP 3134 http://www.python.org/dev/peps/pep-3134/“异常链接和嵌入式回溯”讨论了 Python 3.0 中接受的“链接”异常对象的更改,以指示在处理现有异常期间引发了新异常。
我想做的事情是相关的:我也需要它在早期的Python版本中工作,并且我不需要它用于链接,而仅用于多态性。这样做的正确方法是什么?
Python 3介绍异常链接(如中所述PEP 3134 http://www.python.org/dev/peps/pep-3134/)。这允许在引发异常时引用现有异常作为“原因”:
try:
frobnicate()
except KeyError as exc:
raise ValueError("Bad grape") from exc
捕获的异常(exc
,一个 KeyError)从而成为新异常 ValueError 的一部分(是“原因”)。 “原因”适用于捕获新异常的任何代码。
通过使用此功能,__cause__
属性已设置。内置的异常处理程序还知道如何报告异常的“原因”和“上下文” https://www.python.org/dev/peps/pep-3134/#enhanced-reporting以及回溯。
In Python 2,看来这个用例没有好的答案(如伊恩·比金 http://blog.ianbicking.org/2007/09/12/re-raising-exceptions/ and 内德·巴切尔德 http://nedbatchelder.com/blog/200711/rethrowing_exceptions_in_python.html)。真糟糕。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)