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

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中存在Java .lang. illegalargumentexception——每个人都将在Python中创建自己的BadValueErrors,这是很好理解的,还是有其他的首选方法?


当前回答

我将从ValueError继承

class IllegalArgumentError(ValueError):
    pass

有时创建自己的异常会更好,但要从内置异常继承,这样就尽可能接近您想要的异常。

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

其他回答

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

当内置操作或 函数接收具有的实参 正确的类型,但不合适 价值,而情境则不然 由一个更精确的异常描述 例如IndexError。

——ValueError文档

我将从ValueError继承

class IllegalArgumentError(ValueError):
    pass

有时创建自己的异常会更好,但要从内置异常继承,这样就尽可能接近您想要的异常。

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

在这种情况下,我只看到内置的ValueError。

You would most likely use ValueError (raise ValueError() in full) in this case, but it depends on the type of bad value. For example, if you made a function that only allows strings, and the user put in an integer instead, you would you TypeError instead. If a user inputted a wrong input (meaning it has the right type but it does not qualify certain conditions) a Value Error would be your best choice. Value Error can also be used to block the program from other exceptions, for example, you could use a ValueError to stop the shell form raising a ZeroDivisionError, for example, in this function:

def function(number):
    if not type(number) == int and not type(number) == float:
        raise TypeError("number must be an integer or float")
    if number == 5:
        raise ValueError("number must not be 5")
    else:
        return 10/(5-number)

附注:python内置异常列表,请点击此处: https://docs.python.org/3/library/exceptions.html(这是官方的python数据库)

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

class BadCallError(ValueError):
    pass

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

这不应该是Python中的一个标准异常吗?

一般来说,我希望Python风格能够更清晰地区分函数的错误输入(调用者的错误)和函数内的错误结果(我的错误)。因此可能还会有BadArgumentError来区分参数中的值错误和局部变量中的值错误。