04-断言
11.3 断言
“断言”是健全性检查,用于确保代码没有做什么明显错误的事情。这些健全性检查由 assert
语句执行。如果检查失败,就会抛出异常。在代码中, assert
语句包含以下部分。
assert
关键字。- 条件(即求值为
True
或False
的表达式)。 - 逗号。
- 当条件为
False
时显示的字符串。
assert
语句表达的是:“我断言条件成立,如果条件不成立,则说明某个地方有bug,应立即停止程序。”例如,在交互式环境中输入以下代码:
>>> ages = [26, 57, 92, 54, 22, 15, 17, 80, 47, 73]
>>> ages.sort()
>>> ages
[15, 17, 22, 26, 47, 54, 57, 73, 80, 92]
>>> assert
ages[0] <= ages[-1] # Assert that the first age is <= the last age.
这里的 assert
语句断言 ages
中的第一项应小于或等于最后一项。这是健全性检查;如果 sort()
中的代码没有错误,并且可以完成工作,则该断言为真。
因为表达式 ages[0] <= ages[-1]
求值为 True
,所以 assert
语句不执行任何操作。
但是,假设我们的代码中有一个错误。假设我们不小心调用了 reverse()
列表方法,而不是 sort()
列表方法。在交互式环境中输入以下内容时, assert
语句将引发 AssertionError
:
>>> ages = [26, 57, 92, 54, 22, 15, 17, 80, 47, 73]
>>> ages.reverse()
>>> ages
[73, 47, 80, 17, 15, 22, 54, 92, 57, 26]
>>> assert ages[0] <= ages[-1] # Assert that the first age is <= the last age.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
不像异常,代码不应该用 try
和 except
处理 assert
语句。如果 assert
失败,那么程序就应该崩溃。通过这样的“快速失败”,产生bug和你第一次注意到该bug之间的时间就缩短了。这将减少为了寻找bug的原因而需要检查的代码量。
断言针对的是程序员的错误,而不是用户的错误。断言只能在程序正在开发时失败,用户永远都不会在完成的程序中看到断言错误。对于程序在正常运行中可能遇到的那些错误(如文件没有找到,或用户输入了无效的数据),请抛出异常,而不是用 assert
语句检测它。不应使用 assert
语句来引发异常,因为用户可以选择关闭断言。如果你使用 python -O myscript.py
而不是 python myscript.py
运行Python脚本,那么Python将跳过 assert
语句。如果用户开发的程序需要在具有最佳性能的生产环境中运行,可能会禁用断言。(尽管在很多时候,即使在这种情况下他们也会使断言保持启用状态。)
断言不能替代全面测试。例如,如果先前的 ages
示例设置为 [10, 3, 2, 1, 20]
,则断言 ages[0] <= ages[-1]
不会注意到列表未排序,因为刚好第一个年龄小于等于最后一个年龄,这是断言所做的唯一检查。