为什么assert没有被大量使用?

问题描述 投票:0回答:5

我发现Python 的断言语句是捕获不应该发生的情况的好方法。当代码被认为是正确的时,它可以通过Python优化来删除。

这似乎是在调试模式下运行Python应用程序的完美机制。但看看 django、twisted 和 zope 等几个 Python 项目,

assert
几乎从未被使用过。那么,为什么会出现这种情况呢?

为什么Python社区不经常使用assert语句?

python debugging assert
5个回答
77
投票

我猜

assert
不被更频繁地使用的主要原因是没有人使用Python的“优化”模式

断言是检测编程错误、防止意外情况发生的绝佳工具,但所有这些错误检查都是有代价的。在 C/C++ 等编译语言中,这并不重要,因为断言仅在调试版本中启用,并从发布版本中完全删除。

另一方面,在 Python 中,debugrelease 模式之间没有严格的区别。解释器具有“优化标志”(

-O
),但目前这实际上并没有优化字节码,而只是删除了断言。

因此,大多数 Python 用户只是忽略

-O
标志并在“正常模式”下运行脚本,这是 调试模式,因为启用了断言并且
__debug__
True
,但被视为“生产”准备好了”。

也许切换逻辑会更明智,即默认情况下“优化”并且仅在显式调试模式下启用断言(*),但我想这会让很多用户感到困惑,我怀疑我们是否会看到这样的改变。

((*)这就是 Java VM 的示例,通过使用

-ea
(启用断言)开关。)


38
投票

我想到了几个原因......

这不是主要功能

许多程序员不要被基本原理所困扰,不尊重任何不直接参与程序倒数第二个功能的东西。断言语句旨在用于调试和测试,因此,这是他们无法承受的奢侈品。

单元测试

assert 语句早于单元测试的兴起。虽然断言语句仍然有它的用途,但单元测试现在广泛用于构建一个敌对的环境,用它来敲打子例程及其系统的垃圾。在这种情况下,断言语句开始感觉就像枪战中的刀子。

提高行业对测试的尊重

assert 语句最适合作为最后一道防线。当 C 语言统治世界时,它作为实现新奇的“防御性编程”的好方法,在 C 语言的统治下上升到了崇高而不可触及的高度;它能在灾难濒临崩溃的那一刻识别并捕获它们。这是在测试的价值得到广泛认可和尊重并且灾难变得更加普遍之前。

如今,任何严肃的商业软件未经某种形式的测试就发布,这是闻所未闻的。测试受到重视并已发展成为一个庞大的领域。有测试专业人员和质量保证部门,有大量的清单和正式的签字。在这些情况下,程序员往往不会为断言而烦恼,因为他们相信他们的代码将受到如此多令人厌烦的测试,以至于出现古怪的灾难边缘条件的可能性非常小,可以忽略不计。这并不是说他们是对的,但如果可以将懒惰编程的责任转移到 QA 部门,那为什么不呢?


14
投票

我不是任何这些项目的作者,所以这只是根据我自己的经验的猜测。如果不直接询问这些项目中的人员,您将无法得到具体答案。

当您尝试在自己的应用程序中进行调试等时,断言非常有用。然而,正如您提供的链接中所述,当应用程序能够预测状态并从状态恢复时,使用条件会更好。我没有使用过 zope,但在 Twisted 和 Django 中,它们的应用程序都能够从代码中的许多错误中恢复并继续。从某种意义上说,他们已经“编译”了断言,因为他们实际上可以处理它们。

与此相关的另一个原因是,使用外部库(例如您列出的库)的应用程序通常可能需要进行错误处理。如果库只是使用断言,无论错误是什么,它都会引发

AssertionError
。通过条件,库实际上可以抛出有用的错误,这些错误可以由您的应用程序捕获和处理。


0
投票

根据我的经验,

assert
主要用于程序的开发阶段 - 检查用户定义的输入。
assert
并不是真正需要捕获编程错误。 Python 本身非常有能力捕获真正的编程错误,例如
ZeroDivisionError, TypeError
等。


0
投票

不使用assert,因为代码运行需要更多时间,我们必须牺牲速度

© www.soinside.com 2019 - 2024. All rights reserved.