问题:我应该针对Python中的错误/非法参数组合引发哪个异常?
我想知道在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
-是否众所周知每个人都将BadValueError
在Python中创建自己的s还是存在另一种首选方法?
回答 0
我只会提出ValueError,除非您需要更具体的exceptions。
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
我会继承 ValueError
class IllegalArgumentError(ValueError):
pass
有时最好创建自己的异常,但要从内置异常中继承,该异常应尽可能接近您想要的异常。
如果需要捕获该特定错误,请使用一个名称。
回答 2
我认为处理此问题的最佳方法是python本身处理它的方法。Python引发TypeError。例如:
$ python -c 'print(sum())'
Traceback (most recent call last):
File "<string>", line 1, in <module>
TypeError: sum expected at least 1 arguments, got 0
我们的初级开发人员刚刚在Google搜索“ python异常错误参数”中找到了此页面,而令我惊讶的是,自问这个问题以来,十年来从未出现过明显的(对我而言)答案。
回答 3
我几乎只看到ValueError
过这种情况下使用的内建函数。
回答 4
这取决于参数的问题。
如果参数的类型错误,则引发TypeError。例如,当您获取字符串而不是这些布尔值之一时。
if not isinstance(save, bool):
raise TypeError(f"Argument save must be of type bool, not {type(save)}")
但是请注意,在Python中我们很少进行此类检查。如果参数确实无效,那么一些更深层的功能可能会为我们带来麻烦。而且,如果我们仅检查布尔值,也许某些代码用户以后会向其提供一个字符串,因为它知道非空字符串始终为True。这可能会救他一个演员。
如果参数包含无效值,请引发ValueError。这似乎更适合您的情况:
if recurse and not save:
raise ValueError("If recurse is True, save should be True too")
或在此特定情况下,递归的True值表示保存的True值。由于我认为这是从错误中恢复,因此您可能还希望在日志中抱怨。
if recurse and not save:
logging.warning("Bad arguments in import_to_orm() - if recurse is True, so should save be")
save = True
回答 5
我不确定我是否同意继承ValueError
-我对文档的解释ValueError
是仅应由内建函数引发…从中继承或自己引发它似乎不正确。
当内置操作或函数接收到类型正确但值不合适的参数时引发,并且这种情况没有通过诸如IndexError之类的更精确的异常描述。
回答 6
同意Markus关于提出自己的异常的建议,但是该异常的文字应阐明问题出在参数列表中,而不是单个参数值中。我建议:
class BadCallError(ValueError):
pass
当缺少特定调用所需的关键字参数或参数值分别有效但彼此不一致时使用。 ValueError
当特定参数是正确类型但超出范围时,仍将是正确的。
这不是Python中的标准exceptions吗?
总的来说,我希望Python样式在区分函数的错误输入(调用者的错误)和函数内部的错误结果(我的错误)方面更加犀利。因此,可能还存在BadArgumentError来区分参数中的值错误和本地变量中的值错误。