- 内容提要
- 作者简介
- 技术评审者简介
- 致谢
- 译者序 会编程的人不一样
- 前言
- 本书的读者对象
- 编码规范
- 什么是编程
- 本书简介
- 下载和安装 Python
- 启动 IDLE
- 如何寻求帮助
- 聪明地提出编程问题
- 小结
- 第一部分 Python 编程基础
- 第1章 Python 基础
- 第2章 控制流
- 第3章 函数
- 第4章 列表
- 第5章 字典和结构化数据
- 第6章 字符串操作
- 第二部分 自动化任务
- 第7章 模式匹配与正则表达式
- 第8章 读写文件
- 第9章 组织文件
- 第10章 调试
- 第11章 从 Web 抓取信息
- 第12章 处理 Excel 电子表格
- 第13章 处理 PDF 和 Word 文档
- 第14章 处理 CSV 文件和 JSON 数据
- 第15章 保持时间、计划任务和启动程序
- 第16章 发送电子邮件和短信
- 第17章 操作图像
- 第18章 用 GUI 自动化控制键盘和鼠标
- 附录A 安装第三方模块
- 附录B 运行程序
- 附录C 习题答案
10.3 断言
“断言”是一个心智正常的检查,确保代码没有做什么明显错误的事情。这些心智正常的检查由assert语句执行。如果检查失败,就会抛出异常。在代码中,assert语句包含以下部分:
· assert关键字;
· 条件(即求值为True或False的表达式);
· 逗号;
· 当条件为False时显示的字符串。
例如,在交互式环境中输入以下代码:
>>> podBayDoorStatus = 'open' >>> assert podBayDoorStatus == 'open', 'The pod bay doors need to be "open".' >>> podBayDoorStatus = 'I\'m sorry, Dave. I\'m afraid I can't do that.'' >>> assert podBayDoorStatus == 'open', 'The pod bay doors need to be "open".' Traceback (most recent call last): File "< pyshell#10>", line 1, in < module> assert podBayDoorStatus == 'open', 'The pod bay doors need to be "open".' AssertionError: The pod bay doors need to be "open".
这里将podBayDoorStatus设置为 'open',所以从此以后,我们充分期望这个变量的值是 'open'。在使用这个变量的程序中,基于这个值是 'open' 的假定,我们可能写下了大量的代码,即这些代码依赖于它是 'open',才能按照期望工作。所以添加了一个断言,确保假定podBayDoorStatus是 'open' 是对的。这里,我们加入了信息 'The pod bay doors need to be "open".',这样如果断言失败,就很容易看到哪里出了错。
稍后,假如我们犯了一个明显的错误,把另外的值赋给podBayDoorStatus,但在很多行代码中,我们并没有意识到这一点。这个断言会抓住这个错误,清楚地告诉我们出了什么错。
在日常英语中,assert语句是说:“我断言这个条件为真,如果不为真,程序中什么地方就有一个缺陷。”不像异常,代码不应该用try和except处理assert语句。如果assert失败,程序就应该崩溃。通过这样的快速失败,产生缺陷和你第一次注意到该缺陷之间的时间就缩短了。这将减少为了寻找导致该缺陷的代码,而需要检查的代码量。
断言针对的是程序员的错误,而不是用户的错误。对于那些可以恢复的错误(诸如文件没有找到,或用户输入了无效的数据),请抛出异常,而不是用assert语句检测它。
10.3.1 在交通灯模拟中使用断言
假定你在编写一个交通信号灯的模拟程序。代表路口信号灯的数据结构是一个字典,以 'ns' 和 'ew' 为键,分别表示南北向和东西向的信号灯。这些键的值可以是 'green'、'yellow' 或 'red' 之一。代码看起来可能像这样:
market_2nd = {'ns': 'green', 'ew': 'red'} mission_16th = {'ns': 'red', 'ew': 'green'}
这两个变量将针对Market街和第2街路口,以及Mission街和第16街路口。作为项目启动,你希望编写一个switchLights() 函数,它接受一个路口字典作为参数,并切换红绿灯。
开始你可能认为,switchLights() 只要将每一种灯按顺序切换到下一种顔色:'green' 值应该切换到 'yellow','yellow' 应该切换到 'red','red' 应该切换到'green'。实现这个思想的代码看起来像这样:
def switchLights(stoplight): for key in stoplight.keys(): if stoplight[key] == 'green': stoplight[key] = 'yellow' elif stoplight[key] == 'yellow': stoplight[key] = 'red' elif stoplight[key] == 'red': stoplight[key] = 'green' switchLights(market_2nd)
你可能已经发现了这段代码的问题,但假设你编写了剩下的模拟代码,有几千行,但没有注意到这个问题。当最后运行时,程序没有崩溃,但虚拟的汽车撞车了!
因为你已经编写了剩下的程序,所以不知道缺陷在哪里。也许在模拟汽车的代码中,或者在模拟司机的代码中。可能需要花几个小时追踪缺陷,才能找到switchLights() 函数。
但如果在编写switchLights() 时,你添加了断言,确保至少一个交通灯是红色,可能在函数的底部添加这样的代码:
assert 'red' in stoplight.values(), 'Neither light is red! ' + str(stoplight)
有了这个断言,程序就会崩溃,并提供这样的出错信息:
Traceback (most recent call last): File "carSim.py", line 14, in <module> switchLights(market_2nd) File "carSim.py", line 13, in switchLights assert 'red' in stoplight.values(), 'Neither light is red! ' + str(stoplight) ❶ AssertionError: Neither light is red! {'ns': 'yellow', 'ew': 'green'}
这里重要的一行是AssertionError❶。虽然程序崩溃并非如你所愿,但它马上指出了心智正常检查失败:两个方向都没有红灯,这意味着两个方向的车都可以走。在程序执行中尽早快速失败,可以省去将来大量的调试工作。
10.3.2 禁用断言
在运行Python时传入-O选项,可以禁用断言。如果你已完成了程序的编写和测试,不希望执行心智正常检测,从而减慢程序的速度,这样就很好(尽管大多数断言语句所花的时间,不会让你觉察到速度的差异)。断言是针对开发的,不是针对最终产品。当你将程序交给其他人运行时,它应该没有缺陷,不需要进行心智正常检查。如何用-O选项启动也许并不疯狂的程序,详细内容请参考附录B。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论