Python中子类化特定异常的缺点是什么?

3

我有一个情况,用户可能会提供错误的数据来获取可能不存在的数据点。目前,当出现这些问题时引发的错误类型不清楚或不直观。

在我的API中,我打算创建一个错误来在UI中捕获(或者让UI框架处理并直接向用户报告,我已经测试过并知道可以工作):

class DataError(ValueError):
    '''
    raise this error with a message of what was wrong, 
    will also be caught when catching general ValueErrors
    or other Exceptions that ValueError subclasses
    '''

使用方法:

if user_input not in accepted_values:
    raise DataError('bad user_input: {0}'.format(user_input))

我对自己的方法非常有信心,希望代码无法被攻击。我知道这种方式的优点是,我可以捕获特定的异常而不隐藏其他异常。但我想不出任何缺点。

与仅仅使用 ValueError 抛出错误信息相比,做法的缺点是什么?


1
你需要创建新的异常类型吗?除此之外,我认为为你的应用程序创建更具体的异常类型总是一个好主意。尽管如果没有用户想要从DataErrorValueError中不同地处理它们,那么这可能被认为是多余的。 - dano
1
如果你问我,这样做没有任何真正的缺点,这正是正确的方法。特定的异常比通用的异常更能产生有意义的回溯(和代码)。一个做得非常好的库的例子就是requests.exceptions - Lukas Graf
另外,还可以查看SQLAlchemy(代码 / 文档)以获取一些经过深思熟虑的异常设计。顺便提一下,它还列出了一个DataError。如果对Mike来说足够好,那对我也足够好。 - Lukas Graf
这是一些代码维护的负担。除此之外,“始终捕获最窄可能的异常”原则是一个好的遵循方式,制作自定义异常有助于实现该原则。 - roippi
2个回答

3
我喜欢使用自定义异常。使用 ValueError 和错误消息的缺点是,要捕获这个 特定的 错误,您还需要进行一些字符串匹配,而不仅仅是捕获自定义异常。引发 ValueError 的子类使得更容易看出实现中存在 bug。
另外,ValueError 在实际覆盖范围上相当模糊。

当内置操作或函数接收到具有正确类型但不合适值的参数,并且情况不被更精确地描述时,引发此异常

假设您的 DataError 具有明确定义的有效值范围。在这种情况下,它肯定更为适合,因为它更加具体。

谢谢您的反馈,您帮助了我的确认偏见,但我真的想得到一些明确的下降趋势。 - Russia Must Remove Putin

3
编写自定义异常几乎总是正确的做法。但是,子类化异常存在一些小潜在缺点:
  1. 你的错误是否与标准库中的错误完全对应?例如,实现一个类似于字典的对象,你只需要抛出 KeyError

  2. 你是否子类化了正确的异常?在你的示例中,任何捕获 ValueError 的人也会捕获 DataError。根据你的使用情况,可能有时不适用。

  3. 你子类化的异常是否提供了额外的功能?它是一个类,可能有各种方法。如果你子类化一个异常,你应该验证其所有方法是否适用于你的错误情况。

在其他情况下,异常可能根本不合适。是否有“无值”结果(例如 None[])更加合适?


1)不。 2)是的。 3)不。但感谢您的回答,这些都是潜在的缺点!给你加一分! - Russia Must Remove Putin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接