在现代 Python 中声明自定义异常的正确方法?

新手上路,请多包涵

在现代 Python 中声明自定义异常类的正确方法是什么?我的主要目标是遵循其他异常类所具有的任何标准,以便(例如)我在异常中包含的任何额外字符串都由捕获异常的任何工具打印出来。

我所说的“现代 Python”是指将在 Python 2.5 中运行但对于 Python 2.6 和 Python 3.* 做事方式“正确”的东西。 “自定义”是指 Exception 对象,它可以包含有关错误原因的额外数据:字符串,也可能是与异常相关的其他任意对象。

我被 Python 2.6.2 中的以下弃用警告绊倒了:

 >>> class MyError(Exception):
...     def __init__(self, message):
...         self.message = message
...
>>> MyError("foo")
_sandbox.py:3: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6

似乎很疯狂 BaseException 对于名为 message 的属性具有特殊含义。我从 PEP-352 中收集到,该属性在 2.5 中确实具有特殊含义,他们正试图弃用,所以我猜这个名称(以及那个名称)现在被禁止了?啊。

我也模糊地意识到 Exception 有一些神奇的参数 args ,但我从来不知道如何使用它。我也不确定这是否是未来做事的正确方式;我在网上找到的很多讨论表明他们试图在 Python 3 中取消 args。

更新:两个答案建议覆盖 __init____str__ / __unicode__ / __repr__ 这似乎是很多打字,有必要吗?

原文由 Nelson 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 335
2 个回答

也许我错过了这个问题,但为什么不呢:

 class MyException(Exception):
    pass

要覆盖某些内容(或传递额外的参数),请执行以下操作:

 class ValidationError(Exception):
    def __init__(self, message, errors):
        # Call the base class constructor with the parameters it needs
        super().__init__(message)

        # Now for your custom code...
        self.errors = errors

这样,您可以将错误消息的 dict 传递给第二个参数,然后使用 e.errors 进行处理。

在 Python 2 中,您必须使用这种稍微复杂的 super() 形式:

 super(ValidationError, self).__init__(message)

原文由 gahooa 发布,翻译遵循 CC BY-SA 4.0 许可协议

使用现代 Python 异常,您无需滥用 .message 或覆盖 .__str__().__repr__() 或其中任何一个–如果在引发异常时您想要的只是一条信息性消息,请执行以下操作:

 class MyException(Exception):
    pass

raise MyException("My hovercraft is full of eels")

这将给出以 MyException: My hovercraft is full of eels 结尾的回溯。

如果你想从异常中获得更多的灵活性,你可以传递一个字典作为参数:

 raise MyException({"message":"My hovercraft is full of animals", "animal":"eels"})

然而,要在 except 块中获取这些细节有点复杂。详细信息存储在 args 属性中,这是一个列表。你需要做这样的事情:

 try:
    raise MyException({"message":"My hovercraft is full of animals", "animal":"eels"})
except MyException as e:
    details = e.args[0]
    print(details["animal"])

仍然可以将多个项目传递给异常并通过元组索引访问它们,但这是 非常不鼓励 的(并且甚至打算在一段时间内弃用)。如果您确实需要一条以上的信息,而上述方法对您来说还不够,那么您应该按照本 教程 中的说明创建子类 Exception

 class MyError(Exception):
    def __init__(self, message, animal):
        self.message = message
        self.animal = animal
    def __str__(self):
        return self.message

原文由 frnknstn 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题