- Preface 前言
- 第1章 引论
- 第2章 编程惯用法
- 第3章 基础语法
- 建议19:有节制地使用 from…import 语句
- 建议20:优先使用 absolute import 来导入模块
- 建议21:i+=1 不等于 ++i
- 建议22:使用 with 自动关闭资源
- 建议23:使用 else 子句简化循环(异常处理)
- 建议24:遵循异常处理的几点基本原则
- 建议25:避免 finally 中可能发生的陷阱
- 建议26:深入理解 None 正确判断对象是否为空
- 建议27:连接字符串应优先使用 join 而不是 +
- 建议28:格式化字符串时尽量使用 .format 方式而不是 %
- 建议29:区别对待可变对象和不可变对象
- 建议30:[]、() 和 {}:一致的容器初始化形式
- 建议31:记住函数传参既不是传值也不是传引用
- 建议32:警惕默认参数潜在的问题
- 建议33:慎用变长参数
- 建议34:深入理解 str() 和 repr() 的区别
- 建议35:分清 staticmethod 和 classmethod 的适用场景
- 第4章 库
- 建议36:掌握字符串的基本用法
- 建议37:按需选择 sort() 或者 sorted()
- 建议38:使用 copy 模块深拷贝对象
- 建议39:使用 Counter 进行计数统计
- 建议40:深入掌握 ConfigParser
- 建议41:使用 argparse 处理命令行参数
- 建议42:使用 pandas 处理大型 CSV 文件
- 建议43:一般情况使用 ElementTree 解析 XML
- 建议44:理解模块 pickle 优劣
- 建议45:序列化的另一个不错的选择 JSON
- 建议46:使用 traceback 获取栈信息
- 建议47:使用 logging 记录日志信息
- 建议48:使用 threading 模块编写多线程程序
- 建议49:使用 Queue 使多线程编程更安全
- 第5章 设计模式
- 第6章 内部机制
- 建议54:理解 built-in objects
- 建议55:init() 不是构造方法
- 建议56:理解名字查找机制
- 建议57:为什么需要 self 参数
- 建议58:理解 MRO 与多继承
- 建议59:理解描述符机制
- 建议60:区别 getattr() 和 getattribute() 方法
- 建议61:使用更为安全的 property
- 建议62:掌握 metaclass
- 建议63:熟悉 Python 对象协议
- 建议64:利用操作符重载实现中缀语法
- 建议65:熟悉 Python 的迭代器协议
- 建议66:熟悉 Python 的生成器
- 建议67:基于生成器的协程及 greenlet
- 建议68:理解 GIL 的局限性
- 建议69:对象的管理与垃圾回收
- 第7章 使用工具辅助项目开发
- 第8章 性能剖析与优化
建议8:利用 assert 语句来发现问题
断言(assert)在很多语言中都存在,它主要为调试程序服务,能够快速方便地检查程序的异常或者发现不恰当的输入等,可防止意想不到的情况出现。Python自1.5版本开始引入断言语句,其基本语法如下:
assert expression1 ["," expression2]
其中计算expression 1的值会返回True或者False,当值为False的时候会引发AssertionError,而expression 2是可选的,常用来传递具体的异常信息。
来看一个简单的使用例子:
>>> x =1 >>> y =2 >>> assert x == y,"not equals" Traceback (most recent call last): File "<stdin>", line 1, in <module> AssertionError: not equals >>>
在执行过程中它实际相当于如下代码:
>>> x =1 >>> y =2 >>> if __debug__ and not x == y: ... raise AssertionError("not equals") ... Traceback (most recent call last): File "<stdin>", line 2, in <module> AssertionError: not equals >>>
对Python中使用断言需要说明如下:
1)__debug__的值默认设置为True,且是只读的,在Python2.7中还无法修改该值。
2)断言是有代价的,它会对性能产生一定的影响,对于编译型的语言,如C/C++,这也许并不那么重要,因为断言只在调试模式下启用。但Python并没有严格定义调试和发布模式之间的区别,通常禁用断言的方法是在运行脚本的时候加上-O标志,这种方式带来的影响是它并不优化字节码,而是忽略与断言相关的语句。如:
def foo(x): assert x foo(0)
运行python asserttest.py如下:
Traceback (most recent call last): File "asserttest.py", line 4, in <module> foo(0) File "asserttest.py", line 2, in foo assert x AssertionError
加上-O的参数:python -O asserttest.py便可以禁用断言。
断言实际是被设计用来捕获用户所定义的约束的,而不是用来捕获程序本身错误的,因此使用断言需要注意以下几点:
1)不要滥用,这是使用断言最基本的原则。若由于断言引发了异常,通常代表程序中存在bug。因此断言应该使用在正常逻辑不可到达的地方或正常情况下总是为真的场合。
2)如果Python本身的异常能够处理就不要再使用断言。如对于类似于数组越界、类型不匹配、除数为0之类的错误,不建议使用断言来进行处理。下面的例子中使用断言就显得多余,因为如果传入的参数一个为字符串,另一个为数字或者列表,本身就会抛出TypeError。
>>> def stradd(x,y): ... assert isinstance(x,basestring) ... assert isinstance(y,basestring) ... return x+y
3)不要使用断言来检查用户的输入。如对于一个数字类型,如果根据用户的设计该值的范围应该是2~10,较好的做法是使用条件判断,并在不符合条件的时候输出错误提示信息。
4)在函数调用后,当需要确认返回值是否合理时可以使用断言。
5)当条件是业务逻辑继续下去的先决条件时可以使用断言。如list1和其副本list2,业务继续下去的条件是这两个list必须是一样的,但由于某些不可控因素,如使用了浅拷贝而list1中含有可变对象等,就可以使用断言来判断这两者的关系,如果不相等,则继续运行后面的程序意义不大。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论