对于python中的错误/非法参数组合,我应该引发哪个异常?

Which exception should I raise on bad/illegal argument combinations in Python?

我想知道在Python中指示无效参数组合的最佳实践。我遇到过一些情况,你有这样的功能:

1
2
3
4
5
6
7
8
9
10
11
def import_to_orm(name, save=False, recurse=False):
   """
    :param name: Name of some external entity to import.
    :param save: Save the ORM object before returning.
    :param recurse: Attempt to import associated objects as well. Because you
        need the original object to have a key to relate to, save must be
        `True` for recurse to be `True`.
    :raise BadValueError: If `recurse and not save`.
    :return: The ORM object.
   """

    pass

唯一的麻烦是每个包都有自己的,通常略有不同的BadValueError。我知道在Java中存在EDCOX1,1个-很好地理解,每个人都将在Python中创建自己的EDCOX1,0个s,或者有另一个优选的方法吗?


我只会提出valueerror,除非您需要更具体的异常。

1
2
3
def import_to_orm(name, save=False, recurse=False):
    if recurse and not save:
        raise ValueError("save must be True if recurse is True")

实际上,执行class BadValueError(ValueError):pass没有意义——您的自定义类在使用valueerror时是相同的,那么为什么不使用它呢?


我要从以东王那里继承

1
2
class IllegalArgumentError(ValueError):
    pass

有时最好创建自己的异常,但继承自一个内置的异常,它尽可能接近您想要的。

如果您需要捕获那个特定的错误,有一个名称是很有帮助的。


我只见过这种情况下使用的内置ValueError


我认为处理这一问题的最佳方法是Python本身处理它的方式。python引发类型错误。例如:

1
2
3
4
$ python -c 'print(sum())'
Traceback (most recent call last):
File"<string>", line 1, in <module>
TypeError: sum expected at least 1 arguments, got 0

我们的初级开发人员刚刚在谷歌搜索"python exception wrong arguments"时发现了这个页面,我很惊讶,自这个问题被问到以来的十年里,这个显而易见的(对我来说)答案从未被提出过。


我不确定我是否同意从ValueError继承——我对文档的解释是ValueError只应该由内置的从中继承或自己抚养似乎是不正确的。

Raised when a built-in operation or
function receives an argument that has
the right type but an inappropriate
value, and the situation is not
described by a more precise exception
such as IndexError.

--值错误文档


同意Markus提出的滚动您自己的异常的建议,但是异常的文本应该澄清问题在参数列表中,而不是单个参数值中。我提议:

1
2
class BadCallError(ValueError):
    pass

当缺少特定调用所需的关键字参数或参数值单独有效但彼此不一致时使用。当特定参数类型正确但超出范围时,ValueError仍然是正确的。

这难道不是Python中的标准异常吗?

一般来说,我希望python样式在区分函数的错误输入(调用者的错误)和函数中的错误结果(我的错误)方面更为清晰。所以也可能存在badArgumentError来区分参数中的值错误和局部变量中的值错误。