为什么断言没有被大量使用?

Car*_*res 58 python debugging assert

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

它似乎是在调试模式下运行Python应用程序的完美机制.但是看看django,twisted和zope等几个Python项目,assert几乎从未使用过.那么,为什么会这样呢?

为什么在Python社区中不经常使用断言语句?

Fer*_*yer 59

我想assert不经常使用的主要原因是没有人使用Python的"优化"模式.

断言是检测编程错误,保护自己免受意外情况影响的绝佳工具,但所有这些错误检查都需要付出代价.在诸如C/C++之类的编译语言中,这并不重要,因为断言仅在调试版本中启用,并且完全从发布版本中删除.

另一方面,在Python中,调试发布模式之间没有严格的区别.解释器具有"优化标志"(-O),但目前这实际上并不优化字节代码,而只是删除断言.

因此,大多数Python用户忽略的-O标志和"正常模式",这是他们的运行脚本样的调试模式,因为断言被启用,__debug__True的,但被认为是"投入生产".

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

((*)这是Java VM如何通过-ea(启用断言)开关来实现它.)


Joh*_*Mee 32

想到几个原因......

它不是主要功能

许多程序员不要因为基本原理而陷入困境,不尊重任何不是程序倒数第二功能的直接参与者.断言语句用于调试和测试,因此,它们是一种他们负担不起的奢侈品.

单元测试

断言声明早于单元测试的上升和上升.虽然断言语句仍有其用途,但单元测试现在被广泛用于构建恶意环境,用于从子程序及其系统中剔除垃圾.在这些条件下,断言声明开始像枪战中的刀.

提高了行业对测试的尊重

断言声明最适合作为最后一道防线.当这种语言统治世界时,它在C语言下升到了崇高和不可触及的高度,成为实施新的"防御性编程"的好方法; 它在濒临崩溃的那一刻就认识并捕获了灾难性的灾难.这是在测试的价值得到广泛认可和尊重并且灾难更加普遍之前.

今天,如果没有某种形式的测试,任何严肃的商业软件都会被发布,这是闻所未闻的.测试被认真对待并且已经发展成为一个巨大的领域.有测试专业人​​员和质量保证部门,有大清单和正式签字.在这些条件下,程序员往往不打扰断言,因为他们有信心他们的代码将经受如此多的无聊测试,以至于古怪的灾难条件的可能性非常小,可以忽略不计.这并不是说他们是对的,但如果懒惰编程的责任可以转移到QA部门,那为什么不呢?

  • 实际上,刀具在枪战中并不是那么糟糕,只是距离问题.查看相应的MythBusters剧集;) (6认同)
  • +1:这确实是一个非常好的,被忽视的答案,一般适用于"断言",尤其适用于Python.(你甚至不参考Python) (4认同)
  • [那令人分心](https://www.youtube.com/watch?v=ckz7EmDxhtU):-) (4认同)

Mic*_*att 12

我不是任何这些项目的作者,所以这只是基于我自己的经验猜测.如果没有直接询问这些项目中的人,您将无法获得具体答案.

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

与此相关的另一个原因是,使用外部库(例如您列出的库)的应用程序通常可能需要进行错误处理.如果库只是使用断言,无论错误是什么,它都会引发一个AssertionError.使用条件,库实际上可以抛出可由应用程序捕获和处理的有用错误.

  • @Urthen:你实际上可以控制错误信息:`assert foo == 42,"foo必须是42!"`. (6认同)
  • 我刚刚提到这些项目,因为它们在python社区上非常具有代表性,并且假设它包含python编码的良好实践.我不是想要理解他们为什么不使用asserts语句而是*为什么asserts语句在python社区*中没有被广泛使用. (2认同)