在Python中,抛出内置异常但改变信息可以吗?

28 投票
3 回答
6458 浏览
提问于 2025-04-15 18:45

可以用自定义的文字来抛出一个内置的异常吗?或者也可以用自定义的文字来抛出一个内置的警告吗?

文档上是这么写的:

ValueError异常:当一个内置操作或函数接收到一个参数时(…)

这是不是意味着只有内置操作才应该抛出ValueError异常呢?

在实际操作中,我明白创建一个继承自ValueError或Exception的异常类是安全的。但是,直接抛出ValueError("自定义文字")这样做可以吗?

因为ValueError是内置的,抛出一个带有自定义文字的ValueError可以让用户快速了解问题的类型,相比于自定义的异常类型(比如“ValueErrorSpecificModule”,这不是标准的)。

3 个回答

3

这完全没问题。

不过,你可能想创建一个自己的子类,这样可以和内置的异常区分开来。

比如说,如果你有一个像 dict 的东西,你可以因为常见的原因抛出一个 KeyError,但如果这个 KeyError 实际上是来自你在实现中使用的一个底层字典呢?

抛出一个 KeyError 的子类可以更容易地让你发现是实现中的 bug,而不是单纯因为你的对象里没有这个键。

3

这没问题,我经常这样做。在很多情况下,我看到TypeError比看到MySpecialTypeError更不意外。

在你链接的页面上,我没有看到“内置”这个词:

exception TypeError: Raised when an operation or function is applied to an object of inappropriate type. The associated value is a string giving details about the type mismatch.

也许有人看到你的问题,已经修正了文档。
编辑:看起来你可能把ValueError的文档放错了,应该是TypeError

31

其实,像这样做并没有什么操作上的问题:

raise ValueError("invalid input encoding")

实际上,我在写代码的初稿时经常这样做。这样做的主要问题是,使用你代码的其他人很难准确处理异常;为了捕捉到那个特定的异常,他们需要对捕获到的异常对象进行字符串匹配,这显然是脆弱且繁琐的。因此,最好是自己定义一个ValueError的子类;这样仍然可以作为ValueError被捕获,但也可以作为更具体的异常类被处理。

一个简单的经验法则是,当你有这样的代码:

raise ValueError('some problem: %s' % value)

你可能应该把它替换成这样的:

class SomeProblem(ValueError):
    """
    Raised to signal a problem with the specified value.
    """
# ...
raise SomeProblem(value)

你可以理解为,异常类型说明了发生了什么错误,而消息/属性则说明了是怎么发生的

撰写回答