为什么断言很少被使用?

时间:2022-10-22 15:30:43

I found that Python's assert statement is a good way to catch situations that should never happen. And it can be removed by Python optimization when the code is trusted to be correct.

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

It seems to be a perfect mechanism to run Python applications in debug mode. But looking at several Python projects like django, twisted and zope, the assert is almost never used. So, why does this happen?

在调试模式下运行Python应用程序似乎是一种完美的机制。但是看看几个Python项目,如django、twisted和zope,断言几乎从未使用过。为什么会这样呢?

Why are asserts statements not frequently used in the Python community?

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

4 个解决方案

#1


51  

I guess the main reason for assert not being used more often is that nobody uses Python's "optimized" mode.

我想断言不经常使用的主要原因是没有人使用Python的“优化”模式。

Asserts are a great tool to detect programming mistakes, to guard yourself from unexpected situations, but all this error checking comes with a cost. In compiled languages such as C/C++, this does not really matter, since asserts are only enabled in debug builds, and completely removed from release builds.

断言是发现编程错误的一个很好的工具,可以保护自己不受意外情况的影响,但是所有这些错误检查都是有代价的。在编译语言(如C/ c++)中,这并不重要,因为断言只在调试版本中启用,并且完全从发布版本中删除。

In Python, on the other hand, there is no strict distinction between debug and release mode. The interpreter features an "optimization flag" (-O), but currently this does not actually optimize the byte code, but only removes asserts.

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

Therefore, most Python users just ignore the -O flag and run their scripts in "normal mode", which is kind of the debug mode since asserts are enabled and __debug__ is True, but is considered "production ready".

因此,大多数Python用户只是忽略-O标志,以“正常模式”运行他们的脚本,这是一种调试模式,因为断言是启用的,__debug__是真的,但是被认为是“生产就绪”。

Maybe it would be wiser to switch the logic, i.e., "optimize" by default and only enable asserts in an explicit debug mode(*), but I guess this would confuse a lot of users and I doubt we will ever see such a change.

也许换个逻辑会更明智些,也就是说。,默认情况下是“优化”,并且只在显式调试模式(*)中启用assert,但我想这可能会让很多用户感到困惑,我怀疑我们是否会看到这样的更改。

((*) This is for example how the Java VM does it, by featuring a -ea (enable assertions) switch.)

(*)举例来说,这是Java VM通过提供-ea(启用断言)开关来实现的。

#2


31  

Several reasons come to mind...

我想到了几个原因……

It is not a primary function

它不是主要的功能

Many programmers, lets not get bogged down by the rationale, disrespect anything which is not a direct participant in the program's penultimate functionality. The assert statement is intended for debugging and testing, and so, a luxury they can ill-afford.

许多程序员,让我们不要被基本原理所困扰,不尊重任何不直接参与程序的倒数功能的东西。assert语句用于调试和测试,因此是他们负担不起的奢侈。

Unit Testing

单元测试

The assert statement predates the rise and rise of unit-testing. Whilst the assert statement still has its uses, unit-testing is now widely used for constructing a hostile environment with which to bash the crap out of a subroutine and its system. Under these conditions assert statements start to feel like knives in a gunfight.

assert声明先于单元测试的兴起和兴起。断言语句仍然有它的用途,但是单元测试现在被广泛地用于构建一个敌对的环境,用它从子例程及其系统中清除垃圾。在这种情况下,声明开始让人觉得像是枪战中的刀子。

Improved industry respect for testing

改进行业对测试的尊重

The assert statement serves best as the last line of defence. It rose to lofty and untouchable heights under the C language, when that language ruled the world, as a great way to implement the new-fangled "defensive programming"; it recognises and traps catastrophic disasters in the moment they teeter on the brink. This was before the value of Testing became widely recognised and respected and disasters were substantially more common.

断言声明最好作为最后一道防线。在C语言下,当这种语言统治世界的时候,它就上升到了崇高而不可触及的高度,这是一种实现新型“防御性编程”的好方法;它在灾难的边缘摇摇欲坠的瞬间识别并捕捉灾难。这是在测试的价值得到广泛认可和尊重之前的事情,而灾难在本质上更普遍。

Today, it is unheard of, for any serious commercial software to be released without some form of testing. Testing is taken seriously and has evolved into a massive field. There are Testing professionals and Quality Assurance departments with big checklists and formal sign-offs. Under these conditions programmers tend not to bother with asserts because they have confidence that their code will be subjected to so much tiresome testing that the odds of wacky brink-of-disaster conditions are so remote as to be negligible. That's not to say they're right, but if the blame for lazy programming can be shifted to the QA department, hell why not?

今天,在没有任何形式的测试的情况下发布任何重要的商业软件都是闻所未闻的。测试被认真对待,并且已经发展成一个巨大的领域。有测试专业人员和质量保证部门,有大量的检查清单和正式的签字。在这种情况下,程序员不愿去管断言,因为他们相信他们的代码将会经受如此多的令人厌烦的测试,以至于出现异常的灾难情况的可能性是如此的遥远,以至于可以忽略不计。这并不是说他们是对的,但是如果懒惰编程的责任可以转移到QA部门,为什么不呢?

#3


12  

I'm not an author of any of those projects, so this is just a guess based on my own experiences. Without directly asking people in those projects you won't get a concrete answer.

我并不是这些项目的作者,所以这只是我个人经验的猜测。如果不直接询问那些项目中的人,你将得不到一个具体的答案。

Assert is great when you're trying to do debugging, etc in your own application. As stated in the link you provided, however, using a conditional is better when the application might be able to predict and recover from a state. I haven't used zope, but in both Twisted and Django, their applications are able to recover and continue from many errors in your code. In a sense, they have already 'compiled away' the assertions since they actually can handle them.

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

Another reason, related to that, is that often applications using external libraries such as those you listed might want to do error handling. If the library simply uses assertions, no matter what the error is it will raise an AssertionError. With a conditional, the libraries can actually throw useful errors that can be caught and handled by your application.

另一个与此相关的原因是,经常使用外部库的应用程序(比如您所列出的那些库)可能会想要处理错误。如果库仅仅使用断言,不管错误是什么,它都会引起断言错误。有了条件句,库实际上可以抛出有用的错误,这些错误可以被应用程序捕获和处理。

#4


0  

As per my experience, asserts are majorly used in development phase of a program-to check the user defined inputs. asserts are not really needed to catch programming errors. Python itself is very well capable of trapping genuine programming errors like ZeroDivisionError, TypeError or so.

根据我的经验,断言主要用于程序的开发阶段,用于检查用户定义的输入。断言并不是捕获编程错误所需的。Python本身很有能力捕获真正的编程错误,比如ZeroDivisionError, TypeError之类的。

#1


51  

I guess the main reason for assert not being used more often is that nobody uses Python's "optimized" mode.

我想断言不经常使用的主要原因是没有人使用Python的“优化”模式。

Asserts are a great tool to detect programming mistakes, to guard yourself from unexpected situations, but all this error checking comes with a cost. In compiled languages such as C/C++, this does not really matter, since asserts are only enabled in debug builds, and completely removed from release builds.

断言是发现编程错误的一个很好的工具,可以保护自己不受意外情况的影响,但是所有这些错误检查都是有代价的。在编译语言(如C/ c++)中,这并不重要,因为断言只在调试版本中启用,并且完全从发布版本中删除。

In Python, on the other hand, there is no strict distinction between debug and release mode. The interpreter features an "optimization flag" (-O), but currently this does not actually optimize the byte code, but only removes asserts.

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

Therefore, most Python users just ignore the -O flag and run their scripts in "normal mode", which is kind of the debug mode since asserts are enabled and __debug__ is True, but is considered "production ready".

因此,大多数Python用户只是忽略-O标志,以“正常模式”运行他们的脚本,这是一种调试模式,因为断言是启用的,__debug__是真的,但是被认为是“生产就绪”。

Maybe it would be wiser to switch the logic, i.e., "optimize" by default and only enable asserts in an explicit debug mode(*), but I guess this would confuse a lot of users and I doubt we will ever see such a change.

也许换个逻辑会更明智些,也就是说。,默认情况下是“优化”,并且只在显式调试模式(*)中启用assert,但我想这可能会让很多用户感到困惑,我怀疑我们是否会看到这样的更改。

((*) This is for example how the Java VM does it, by featuring a -ea (enable assertions) switch.)

(*)举例来说,这是Java VM通过提供-ea(启用断言)开关来实现的。

#2


31  

Several reasons come to mind...

我想到了几个原因……

It is not a primary function

它不是主要的功能

Many programmers, lets not get bogged down by the rationale, disrespect anything which is not a direct participant in the program's penultimate functionality. The assert statement is intended for debugging and testing, and so, a luxury they can ill-afford.

许多程序员,让我们不要被基本原理所困扰,不尊重任何不直接参与程序的倒数功能的东西。assert语句用于调试和测试,因此是他们负担不起的奢侈。

Unit Testing

单元测试

The assert statement predates the rise and rise of unit-testing. Whilst the assert statement still has its uses, unit-testing is now widely used for constructing a hostile environment with which to bash the crap out of a subroutine and its system. Under these conditions assert statements start to feel like knives in a gunfight.

assert声明先于单元测试的兴起和兴起。断言语句仍然有它的用途,但是单元测试现在被广泛地用于构建一个敌对的环境,用它从子例程及其系统中清除垃圾。在这种情况下,声明开始让人觉得像是枪战中的刀子。

Improved industry respect for testing

改进行业对测试的尊重

The assert statement serves best as the last line of defence. It rose to lofty and untouchable heights under the C language, when that language ruled the world, as a great way to implement the new-fangled "defensive programming"; it recognises and traps catastrophic disasters in the moment they teeter on the brink. This was before the value of Testing became widely recognised and respected and disasters were substantially more common.

断言声明最好作为最后一道防线。在C语言下,当这种语言统治世界的时候,它就上升到了崇高而不可触及的高度,这是一种实现新型“防御性编程”的好方法;它在灾难的边缘摇摇欲坠的瞬间识别并捕捉灾难。这是在测试的价值得到广泛认可和尊重之前的事情,而灾难在本质上更普遍。

Today, it is unheard of, for any serious commercial software to be released without some form of testing. Testing is taken seriously and has evolved into a massive field. There are Testing professionals and Quality Assurance departments with big checklists and formal sign-offs. Under these conditions programmers tend not to bother with asserts because they have confidence that their code will be subjected to so much tiresome testing that the odds of wacky brink-of-disaster conditions are so remote as to be negligible. That's not to say they're right, but if the blame for lazy programming can be shifted to the QA department, hell why not?

今天,在没有任何形式的测试的情况下发布任何重要的商业软件都是闻所未闻的。测试被认真对待,并且已经发展成一个巨大的领域。有测试专业人员和质量保证部门,有大量的检查清单和正式的签字。在这种情况下,程序员不愿去管断言,因为他们相信他们的代码将会经受如此多的令人厌烦的测试,以至于出现异常的灾难情况的可能性是如此的遥远,以至于可以忽略不计。这并不是说他们是对的,但是如果懒惰编程的责任可以转移到QA部门,为什么不呢?

#3


12  

I'm not an author of any of those projects, so this is just a guess based on my own experiences. Without directly asking people in those projects you won't get a concrete answer.

我并不是这些项目的作者,所以这只是我个人经验的猜测。如果不直接询问那些项目中的人,你将得不到一个具体的答案。

Assert is great when you're trying to do debugging, etc in your own application. As stated in the link you provided, however, using a conditional is better when the application might be able to predict and recover from a state. I haven't used zope, but in both Twisted and Django, their applications are able to recover and continue from many errors in your code. In a sense, they have already 'compiled away' the assertions since they actually can handle them.

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

Another reason, related to that, is that often applications using external libraries such as those you listed might want to do error handling. If the library simply uses assertions, no matter what the error is it will raise an AssertionError. With a conditional, the libraries can actually throw useful errors that can be caught and handled by your application.

另一个与此相关的原因是,经常使用外部库的应用程序(比如您所列出的那些库)可能会想要处理错误。如果库仅仅使用断言,不管错误是什么,它都会引起断言错误。有了条件句,库实际上可以抛出有用的错误,这些错误可以被应用程序捕获和处理。

#4


0  

As per my experience, asserts are majorly used in development phase of a program-to check the user defined inputs. asserts are not really needed to catch programming errors. Python itself is very well capable of trapping genuine programming errors like ZeroDivisionError, TypeError or so.

根据我的经验,断言主要用于程序的开发阶段,用于检查用户定义的输入。断言并不是捕获编程错误所需的。Python本身很有能力捕获真正的编程错误,比如ZeroDivisionError, TypeError之类的。