使用assert验证python中有关参数的假设是不好的做法吗?

Is it bad practice to use assert to verify assumptions about arguments in python?

我正在编写一个类,其__init__使用id或slug参数,但不是两者都使用。 我想验证参数是否符合预期。 将assert用于验证关于参数的假设的特定目的是否合适和良好实践,或者如果参数不符合预期,我是否应该引发异常?

例如。,

1
2
def __init__(self, id=None, slug=None):
    assert((id or slug) and not (id and slug))


原始问题的答案("使用断言来验证python中的内部假设是不好的做法?")绝对没有。这是每个人都同意断言有益的一件事。但是你在问题中描述的不是内部假设的验证:它是对外部输入的验证。一个TypeError,一个ValueError,另一个内置异常(或者可能是一个自定义异常,尽管应该保守一个)给API的用户提供了更有用的反馈。更糟糕的是,断言可能(并且,在某些环境中,通常是)被完全删除,这意味着您的代码将默默地做错事。


如果这是关于代码健全性的,正如您所描述的那样,断言是正确的使用方法。如果这是关于输入验证,则不应使用assert。特别是,用户不应该通过向其提供垃圾来触发断言。断言只能由于程序中的错误而触发。

编辑:正如我刚刚从评论中学到的,Python还允许您完全关闭断言(意味着它们不会被评估,因此不会失败)。这应该是正确的答案(除了使用像汇编或C这样的不同语言)到性能问题,如果有的话。


失败时,Assert会引发AssertionError。当参数不正确时,python标准库经常引发ValueError - 当你使用错误数量的参数调用函数时,或者TypeError

考虑:

1
2
int("15f")     #ValueError
int("15",2,3)  #TypeError

你需要问自己的问题(从API的角度来看)哪个是最合乎逻辑的,你的函数可以提出错误的输入?无论您选择什么,请确保将其记录得很好,这样您的用户就可以知道如何处理错误。