【问题标题】:Catch Built-in Exception (rather than self defined)捕获内置异常(而不是自定义)
【发布时间】:2016-04-29 12:17:21
【问题描述】:

我想修补一个库来捕获内置的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()

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

如何让 Python 捕获内置的 ConnectionError

【问题讨论】:

  • 关于您的免责声明部分,它与范围分辨率有关,因此您是对的,因为最后检查了内置插件。如果你愿意,可以看看这个SO answer

标签: python class exception namespaces


【解决方案1】:

使用builtins 模块,即intConnectionError 等内置名称所在的命名空间的显式名称。

import builtins

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

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


如果你想要在 Python 2 和 Python 3 中都可以工作的代码……好吧,异常层次在 Python 2 中看起来很不一样,而且 ConnectionError 甚至都不存在,所以它不像决定是否使用 @ 那样简单987654329@ 或__builtin__builtins/__builtin__ 这件事至少很容易解决。

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

try:
    import builtins
except ImportError:
    import __builtin__ as builtins

暂时假设 Python 2 存在 ConnectionError,您可以在隐藏名称之前保存对内置 ConnectionError 的引用:

_builtin_ConnectionError = ConnectionError

class ConnectionError(LibraryError):
    ...

【讨论】:

  • 谢谢。另一个问题是原作者编写了在 Python2 中运行的库 在 Python3 中运行 - 所以我可能无法在不破坏 Python2 支持的情况下 import builtins :(
  • @speendo:try: import builtinsexcept ImportError: import __builtin__ as builtins。当模块可能存在或可能不存在时,捕获 ImportError 是非常标准的。或者,您可以在隐藏名称之前保存对内置 ConnectionError 的引用:_builtin_ConnectionError = ConnectionError
  • 哦,最后一个选项将是一个很好的方法来处理它,而不需要太多的黑客攻击!不过,我会问原作者是否愿意重命名他的 ConnectionError,这将进一步提高可读性:)
  • @speendo: 等等,如果你需要在 Python 2 和 Python 3 上都可以运行的代码,你只会捕获 OSError 而不是 ConnectionError,因为 Python 2 没有 ConnectionError .
  • @speendo:实际上,捕捉 OSError 是行不通的,因为异常层次结构的变化比我意识到的要多。在 Python 2 中,socket.error 甚至不是 OSError 的后代。
【解决方案2】:

使用 ConnectionError 以及 builtins 库中定义的其他异常:

import builtins

try:
    # connection error raised
except builtins.ConnectionError as conerr:
    # handle stuff

【讨论】:

  • 谢谢!我上面的评论当然也适合你的回答
  • 感谢您的大力帮助!我真的很感激!我仍然会接受@user2357112 的回答,只是因为它更广泛一些。但请继续努力!
  • @speendo 我真的不介意;没有必要证明你的接受是合理的:-)
猜你喜欢
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 2017-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-31
相关资源
最近更新 更多