捕捉内置异常(而不是自定义)(Catch Built-in Exception (rather than self defined))

我想修补一个库来捕获内置的ConnectionError (它继承自OSError)。

到现在为止还挺好。 碰巧,库有一个“自定义”异常,也称为ConnectionError:

class LibraryError(Exception): pass class ConnectionError(LibraryError): pass

我想,如果我现在试着去捕捉一个ConnectionError ,就像这样做

try: do_something() except ConnectionError as e: try_to_get_it_right_again()

我只会捕获继承自LibraryError的自定义ConnectionError 。 (免责声明:我必须承认,我自己没有测试过,因为我不知道如何)。

我如何获得Python来捕获内置的ConnectionError ?

I want to patch a library to catch the built-in ConnectionError (which inherits from OSError).

So far so good. As it happens, the library has a "self-defined" Exception that is also called ConnectionError:

class LibraryError(Exception): pass class ConnectionError(LibraryError): pass

I guess, if I now tried to catch a ConnectionError, doing something like

try: do_something() except ConnectionError as e: try_to_get_it_right_again()

I would only catch the self-defined ConnectionError, which inherits from LibraryError. (Disclaimer: I have to admit, I haven't tested that myself, as I didn't know how).

How would I get Python to catch the built-in ConnectionError?

最满意答案

使用builtins模块,这是内置名称(如int和ConnectionError存在的名称空间的显式名称。

import builtins try: ... except builtins.ConnectionError: ...

在Python 2中,这将是__builtin__ ,尽管Python 2没有ConnectionError 。 请注意__builtins__是它自己的奇怪的东西; 即使它看起来像你想要的,但它不是。


如果你想要在Python 2和Python 3中都能正常工作的代码,Python 2中的异常层次结构看起来不同,并且ConnectionError甚至不存在,所以它不像决定是使用builtins还是__builtin__那样简单。 至少, builtins / __builtin__事情很容易解决。

要根据Python版本导入正确的模块,您可以捕获ImportError并导入其他模块:

try: import builtins except ImportError: import __builtin__ as builtins

假设Python 2具有ConnectionError,您可以在映射名称之前保存对内置ConnectionError的引用:

_builtin_ConnectionError = ConnectionError class ConnectionError(LibraryError): ...

Use the builtins module, the explicit name for the namespace where built-in names like int and ConnectionError live.

import builtins try: ... except builtins.ConnectionError: ...

In Python 2, this would be __builtin__, although Python 2 doesn't have ConnectionError. Note that __builtins__ is its own weird thing; even if it looks like what you want, it's not.


If you want code that works in both Python 2 and Python 3... well, the exception hierarchy looks pretty different in Python 2, and ConnectionError doesn't even exist, so it's not as simple as deciding whether to use builtins or __builtin__. The builtins/__builtin__ thing is easy enough to solve, at least.

To import the right module depending on Python version, you can catch the ImportError and import the other module:

try: import builtins except ImportError: import __builtin__ as builtins

Pretending for a moment that Python 2 has ConnectionError, you could save a reference to the built-in ConnectionError before shadowing the name:

_builtin_ConnectionError = ConnectionError class ConnectionError(LibraryError): ...

更多推荐