如何在Python中指示无效参数?

14 投票
2 回答
16913 浏览
提问于 2025-04-16 12:30

可能重复的问题:
python:我应该使用ValueError还是创建自己的子类来处理无效字符串?

我在阅读内置异常时看到:

所有用户定义的异常也应该从这个类派生,指的就是异常类。

我还看到一个ValueError,它说:

当一个内置操作或函数接收到一个类型正确但值不合适的参数时,就会抛出这个异常,而且这种情况没有更精确的异常来描述,比如IndexError。

如果我想为无效参数抛出一个异常(类似于Ruby中的ArgumentError),我该怎么做呢?我应该直接抛出ValueError,还是更好地创建一个继承自ValueError的子类,并给它起个能说明意图的名字?

在我的情况下,我接受一个关键参数,但我想限制这个关键参数中的字符集,只允许/\A[\w.]+\Z/(Perl/Ruby正则表达式)中的字符。

2 个回答

2

ValueError 这个错误看起来很适合你遇到的情况。

12

我觉得大致的意思是这样的:ValueError通常表示某种客户端错误(这里的“客户端”指的是使用你接口的程序员)。在Python中,异常大致可以分为两种类型:

  • 一些不常见的情况,但代码本身是正常工作的;这时候客户端并没有错。

  • 使用错误,比如某个接口被错误使用,或者通过一系列接口调用,系统达到了不一致的状态;这时候就要怪客户端了。

在我看来,对于第一种情况,创建异常类的层次结构是有意义的,这样客户端代码可以更细致地控制在不常见情况下该怎么处理。

而在第二种情况下,比如ValueError就是一个例子,你是在告诉客户端他们做错了什么。这里不需要那么复杂的异常层次结构,因为客户端代码应该修正过来,做到正确的事情(例如,首先传入正确的参数类型)。

总结一下:直接使用ValueError,但要加上有帮助的提示信息(例如,raise ValueError("抱歉,我不能让你这么做,Dave。-HAL 9000"))。除非你真的认为有人会想捕获SubClassError而不想捕获其他的ValueError,否则就不要去创建子类。

话说回来,正如你提到的,Python的内置库在某些情况下确实会对ValueError进行子类化(例如UnicodeError)。

撰写回答