【发布时间】:2010-10-16 07:30:48
【问题描述】:
我正在编写一个模块,并希望为它可以引发的异常有一个统一的异常层次结构(例如,从 FooError 抽象类继承所有 foo 模块的特定异常)。这允许模块的用户捕获那些特定的异常并在需要时清楚地处理它们。但是从模块中引发的许多异常都是由于其他一些异常而引发的;例如由于文件上的 OSError,某些任务失败。
我需要“包装”捕获的异常,使其具有不同的类型和消息,以便通过捕获异常的任何内容,可以在传播层次结构中进一步获取信息。但我不想丢失现有的类型、消息和堆栈跟踪;对于试图调试问题的人来说,这些都是有用的信息。顶级异常处理程序不好,因为我试图在异常进入传播堆栈之前对其进行修饰,而顶级处理程序为时已晚。
通过从现有类型(例如class FooPermissionError(OSError, FooError))派生我的模块foo 的特定异常类型,部分解决了这个问题,但这并没有使将现有异常实例包装在新类型中变得更容易,也不修改消息。
Python 的 PEP 3134“异常链接和嵌入式回溯”讨论了 Python 3.0 中接受的“链接”异常对象的更改,以表明在处理现有异常期间引发了新异常。
我正在尝试做的是相关的:我需要它在早期的 Python 版本中也能工作,而且我需要它不是用于链接,而只是用于多态性。这样做的正确方法是什么?
【问题讨论】:
-
异常已经是完全多态的——它们都是异常的子类。你想做什么? “不同的消息”对于顶级异常处理程序来说是相当微不足道的。你为什么要换班?
-
正如问题中所解释的(现在,感谢您的评论):我正在尝试修饰我捕获的异常,以便它可以进一步传播更多信息但不会丢失任何信息。顶级处理程序为时已晚。
-
请看我的CausedException class,它可以在 Python 2.x 中做你想做的事。同样在 Python 3 中,如果您想给出多个原始异常作为异常原因,它也很有用。也许它符合您的需求。
-
对于 python-2 我做了类似于@DevinJeanpierre 但我只是附加一个新的字符串消息:
except Exception as e-->raise type(e), type(e)(e.message + custom_message), sys.exc_info()[2]--> this solution is from another SO question。这不漂亮但实用。
标签: python exception-handling polymorphism