4

我正在编写一个__init__使用 id 或 slug 参数但不能同时使用两者的类。我想验证参数是否符合预期。将 an 用于验证有关参数的假设的特定目的是否正确和良好的做法assert,或者如果参数不符合预期,我应该提出异常?

例如,

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

3 回答 3

10

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

于 2012-11-23T19:09:08.797 回答
7

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

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

于 2012-11-23T19:07:52.020 回答
4

断言AssertionError失败时引发。ValueError当参数不完全正确时,python 标准库经常引发- 或者TypeError当您使用错误数量的参数调用函数时:

考虑:

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

您需要问自己的问题(从 API 的角度来看)是,对于您的函数来说,在错误输入时提出哪个最合乎逻辑?无论您选择什么,请确保将其记录在案,以便您的用户知道如何处理出现的错误。

于 2012-11-23T19:07:45.110 回答