我发现Python's assert statement是捕捉should never happen情况的好方法。当代码被认为是正确的时,可以通过Python优化删除它。
这似乎是在调试模式下运行Python应用程序的完美机制。但是看看django,twisted和zope等几个Python项目,assert
几乎从未使用过。那么,为什么会这样呢?
为什么在Python社区中不经常使用断言语句?
答案 0 :(得分:54)
我想assert
未被更频繁使用的主要原因是没有人使用Python的“优化”模式。
断言是检测编程错误,保护自己免受意外情况影响的绝佳工具,但所有这些错误检查都需要付出代价。在诸如C / C ++之类的编译语言中,这并不重要,因为断言仅在调试版本中启用,并且完全从发布版本中删除。
另一方面,在Python中, debug 和 release 模式之间没有严格的区别。解释器具有“优化标志”(-O
),但目前这实际上并不优化字节代码,而只是删除断言。
因此,大多数Python用户只是忽略-O
标志并以“正常模式”运行他们的脚本,这是类型的调试模式,因为断言已启用且{{1} }是__debug__
,但被认为是“生产就绪”。
可能更明智的是切换逻辑,即默认情况下“优化”并且只在显式调试模式(*)中启用断言,但我想这会让很多用户感到困惑,我怀疑我们会看到这样的改变。
((*)这是Java VM如何通过True
(启用断言)开关来实现它。)
答案 1 :(得分:32)
想到几个原因......
这不是主要功能
许多程序员不要因为基本原理而陷入困境,不尊重任何不是程序倒数第二功能的直接参与者。断言语句用于调试和测试,因此是他们负担不起的奢侈品。
单元测试
断言声明早于单元测试的上升和上升。虽然assert语句仍有其用途,但单元测试现在被广泛用于构建恶意环境,用于从子程序及其系统中剔除垃圾。在这些条件下,断言声明开始像枪战中的刀。
提高了行业对测试的尊重
断言声明最适合作为最后一道防线。当语言统治世界时,它在C语言下升到了崇高和不可触及的高度,成为实施新的防御性编程的好方法。它在濒临崩溃的那一刻就认识并捕获了灾难性的灾难。这是在测试的价值得到广泛认可和尊重以及灾难更加普遍之前。
今天,如果没有某种形式的测试,任何严肃的商业软件都会被发布,这是闻所未闻的。测试被认真对待并且已经发展成为一个巨大的领域。有测试专业人员和质量保证部门,有大清单和正式签字。在这些条件下,程序员往往不打扰断言,因为他们有信心他们的代码将经受如此多的无聊测试,以至于古怪的灾难条件的可能性非常小,可以忽略不计。这并不是说他们是对的,但如果懒惰编程的责任可以转移到QA部门,那为什么不呢?
答案 2 :(得分:12)
我不是任何这些项目的作者,所以这只是基于我自己的经验猜测。如果不直接询问那些项目中的人,你就不会得到具体的答案。
当您尝试在自己的应用程序中进行调试等时,Assert很棒。但是,如您提供的链接中所述,当应用程序可能能够预测并从状态恢复时,使用条件更好。我没有使用过zope,但是在Twisted和Django中,他们的应用程序能够从代码中的许多错误中恢复并继续。从某种意义上说,他们已经“编译”了断言,因为他们实际上可以处理它们。
与此相关的另一个原因是,使用外部库(例如您列出的库)的应用程序通常可能需要进行错误处理。如果库只是使用断言,则无论错误是什么,它都会引发AssertionError
。使用条件,库实际上可以抛出可由应用程序捕获和处理的有用错误。
答案 3 :(得分:0)
根据我的经验,assert
主要用于程序的开发阶段 - 检查用户定义的输入。捕捉编程错误并不需要assert
。 Python本身非常能够捕获像ZeroDivisionError, TypeError
左右这样的真正的编程错误。