《effective python》笔记 第8章 部署
- 54. 考虑用模块级别的代码来配置不同的部署环境
- 55. 通过repr字符串来输出调试信息
- 56. 用unitest来测试全部代码
- 57. 考虑用pdb实现交互式调试
- 58. 先分析性能,然后再优化
- 59. 通过tracemalloc来掌握内存的使用及泄露情况
最终我们要将程序从开发环境部署到生产环境。令程序支持几套不同的配置方案颇有难度。某些内置的Python模块可以帮我们优化程序的调试、优化、测试,努力提升程序品质。
54. 考虑用模块级别的代码来配置不同的部署环境
-
使用配置项明确指出现在运行的是开发环境还是生产环境。
-
可以通过
sys
和os
模块查询当前宿主机器的特性,以此决定模块的内容、逻辑。
55. 通过repr字符串来输出调试信息
-
使用普通的print输出的调试信息有两个问题:
-
不能清晰地表明变量的类型。例如
print(5)
和print('5')
的输出是一样的。 -
对象被打印前会被自动调用repr函数,但打印出是类似
<__main__.SomeClass object at 0x107880ba8>
的内容,不是很有用。
-
-
第1个问题,需要使用
print(repr(5))
或者print('%r',5)
才能打印出来。 -
第2个问题,需要为我们自己的类定义
__repr__
方法。如果是我们无法改写的类,可以通过print(obj.__dict__)
来观察其内部信息。
56. 用unitest来测试全部代码
-
Python的动态特性,一方面阻碍了静态类型检查,另一方面使得我们可以更方便的编写测试代码,我们动态覆盖相关行为来实现更灵活的测试。
-
Python内置的
unitest
模块可以方便的开发测试用例。请自行学习unitest模块的使用方法(主要是TestCase
类)。 -
Python3还有
unitest.mock
模块可以动态替换受测程序中的行为。
57. 考虑用pdb实现交互式调试
- 可以在代码中加入
import pdb; pdb.set_trace()
这么一行代码,运行到此处时将会启动交互式调试界面:
-> import pdb; pdb.set_trace() # 这样一行代码可以很方便的被注释掉
(Pdb)
- 请自行学习pdb的更多使用方法。
58. 先分析性能,然后再优化
-
Python程序的运行效率可能与我们预想的结果有很大差距,我们可以使用内置的性能分析工具(profiler)。
-
有两种内置的profiler,一种是Python实现的(名字叫profile),一种是C实现的扩展模块(名字叫cProfile)。推荐后者,因为它对受测程序产生的影响小很多,更加准确。
-
请自行学习cProfile模块的使用方法(主要是runcall方法分析性能,通过Stats对象获取分析数据)。
59. 通过tracemalloc来掌握内存的使用及泄露情况
-
Python的默认实现
CPython
通过引用计数和循环引用检测(cycle detector)来进行垃圾回收。通常我们不用担心垃圾回收问题,但是有时我们还是因为保留了过多的引用导致内存耗尽。 -
我们可以使用内置的gc模块查询内存分配情况,主要是使用gc.get_objects()方法获得所有分配的对象,选取其中最小的样本展示出来,比如打印
gc.get_objects()[:3]
。 -
Python3.4新推出的内置模块
tracemalloc
可以知道对象分配的地点。请自行学习该模块的使用方法。