[英]Which exception should I raise on bad/illegal argument combinations in 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
- 是否很好理解每个人都会在 Python 中创建自己的BadValueError
或者是否有另一种首选方法?
我只会提高ValueError ,除非您需要更具体的异常..
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相同,那么为什么不使用它呢?
我会从ValueError
继承
class IllegalArgumentError(ValueError):
pass
有时最好创建自己的异常,但从内置异常继承,这尽可能接近您想要的。
如果您需要捕获该特定错误,拥有一个名称会很有帮助。
我认为处理这个问题的最好方法是 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
我们的初级开发人员刚刚在谷歌搜索“python 异常错误参数”中找到了这个页面,我很惊讶自问这个问题以来的十年里,没有人提出明显的(对我来说)答案。
这取决于参数的问题是什么。
如果参数的类型错误,则引发 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")
或者在这种特定情况下,递归的真值意味着保存的真值。 由于我认为这是从错误中恢复,您可能还想在日志中抱怨。
if recurse and not save:
logging.warning("Bad arguments in import_to_orm() - if recurse is True, so should save be")
save = True
我主要只是看到在这种情况下使用的内置ValueError
。
在这种情况下,您很可能会使用ValueError
( raise ValueError()
in full),但这取决于错误值的类型。 例如,如果您创建了一个只允许字符串的函数,而用户输入的是一个整数,那么您将使用TypeError
。 如果用户输入了错误的输入(意味着它具有正确的类型但不符合某些条件),则Value Error
将是您的最佳选择。 Value
Error 也可用于阻止程序发生其他异常,例如,您可以使用ValueError
来阻止 shell 表单引发ZeroDivisionError
,例如,在此函数中:
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)
PS 有关 python 内置异常的列表,请转到此处: https : //docs.python.org/3/library/exceptions.html (这是官方 python 数据库)
我不确定我是否同意从ValueError
继承——我对文档的解释是ValueError
只应该由内置函数引发……从它继承或自己引发似乎不正确。
当内置操作或函数接收到类型正确但值不合适的参数时引发,并且这种情况没有用更精确的异常(如 IndexError)描述。
同意 Markus 的建议,推出您自己的例外,但例外的文本应阐明问题出在参数列表中,而不是单个参数值中。 我建议:
class BadCallError(ValueError):
pass
当缺少特定调用所需的关键字参数,或参数值单独有效但彼此不一致时使用。 当特定参数是正确类型但超出范围时, ValueError
仍然是正确的。
这不应该是 Python 中的标准异常吗?
一般来说,我希望 Python 风格在区分函数的错误输入(调用者的错误)和函数中的错误结果(我的错误)方面更加清晰。 所以也可能有一个 BadArgumentError 来区分参数中的值错误和局部变量中的值错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.