生产中可以接受断言方法吗?

Shi*_*raz 6 python return exception

在工作中,我遇到了这种方法,它困扰着我。事实上,方法的名称、文档和实现并没有真正相互匹配(并且传递 true 使 true 的条件变为 false),我不明白拥有这样一个方法的意义(这是生产代码):

# @brief An utility method that raises if the singleton is not in a good
# state
#@param expect_instanciated bool : if True we expect that the class is
# allready instanciated, else not
# @throw RuntimeError
@classmethod
def singleton_assert(cls, expect_instanciated=False):
    if expect_instanciated:
        if not cls.started():
            raise RuntimeError("The Settings class is not started yet")
    else:
        if cls.started():
            raise RuntimeError("The Settings class is already started")
Run Code Online (Sandbox Code Playgroud)

以下是我的担忧:

  • 这个“断言”函数并没有告诉我太多......而且会让客户认为它总是会返回一个布尔值。
  • “无”是没有意义的,没有提供给客户的信息,从不。客户端无法保存或传递该信息,或者必须编写几行来简单地设置一个布尔变量;
  • 我认为当该方法无法正常工作时,应该抛出异常,以应对意外行为。在这里,很明显!
  • 这种方法限制了客户端处理他可能不关心的异常,并且在不使用 try..catch 块的情况下不会给他自己的选择,这对我来说似乎不太好;
  • 那些引发的异常似乎假装是一个正常的返回值,就像“file_exists()”方法在没有文件时引发异常,在没有文件时引发异常;
  • 对我来说,将这种方法留在生产中意味着我对代码的稳定性或设计没有信心。单例实例不应超过一个。例如,python 的exists()方法不是断言,并且总是返回一个布尔值!我认为没有任何理由让这种方法按原样投入生产(并且应该实际删除,或移至单元测试套件)。

我非常确信这种方法是错误的。然而,知道这个特定的代码是否正常是一回事,知道以更一般的方式是否是这种情况是另一回事。因此:

可以将断言方法投入生产吗?

编辑:正如评论员指出的那样,这是一个相当常见的断言方法(就像在 python 核心代码中一样)。

但是,针对此类方法进行更深入的研究人员,我严格运行“单元测试”或“调试”上下文,有些人声称不应将其推入生产。如果它是在测试/调试环境中,我就不会对这件作品进行窃听。

因此:是否有更多关于让 assert 方法在生产环境中滑动的可行性的说明?

编辑 2:断言什么时候应该留在生产代码中?这是我在谷歌搜索时创建的唯一演讲之一。我还不清楚。

Joh*_*ica 5

这个方法很好。

这个“断言”函数并没有告诉我太多......而且会让客户认为它总是会返回一个布尔值。

assert是许多语言中的常用习语。目的是检查预期始终为真的条件。失败的断言表示编码错误。因此,该方法正常不返回任何内容,如果条件失败则抛出异常。

“无”是没有意义的,没有提供给客户的信息,从不。客户端无法保存或传递该信息,或者必须编写几行来简单地设置一个布尔变量;

无需检查断言的结果。

我认为当该方法无法正常工作时,应该抛出异常,以应对意外行为。在这里,很明显!

断言应该在 100% 的时间内通过。仅当条件意外失败时才会抛出异常。

这种方法限制了客户端处理他可能不关心的异常,并且在不使用 try..catch 块的情况下不会给他自己的选择,这对我来说似乎不太好;

永远不应该处理断言异常。它们表示编码错误。不期望程序应该从错误中恢复。通常最好直接崩溃。

我正在区分错误和其他特殊情况。找不到文件之类的 I/O 错误是您需要计划的用户或系统错误。您应该捕获这些异常并从中恢复。空指针异常或断言错误是错误的迹象。您无法从它们中恢复过来,因为当它们发生时,谁知道还有什么地方出了问题?错误需要修复,而不是处理。

但是,针对此类方法进行更深入的研究人员,我严格运行“单元测试”或“调试”上下文,有些人声称不应将其推入生产。如果它是在测试/调试环境中,我就不会对这件作品进行窃听。

在生产代码中运行断言并没有错。它们不是有害的,也不是糟糕的设计。事实上,它们是很好的设计。他们确认系统运行正常。

人们有时在生产代码中禁用断言的原因是为了性能。他们不想要额外检查的开销。就个人而言,我不处理任何性能敏感的程序,因此我始终启用断言。额外的安全性非常值得几次if检查的微不足道的成本。

  • 如果某些东西在运行时确实需要额外的安全性,您应该明确声明为“if ... raise”,否则断言应被视为仅对类型检查器/测试有用,而不是产品代码的一部分(除了满足 mypy支票之类的)...为什么?因为如果有人碰巧使用“-O”运行 python,那么你的所有断言都会被禁用,使它们等同于不安全。 (2认同)