- 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章 性能剖析与优化
建议82:使用 memory_profiler 和 objgraph 剖析内存使用
Python还提供了一些工具可以用来查看内存的使用情况以及追踪内存泄露(如memory_profiler、objgraph、cProfile、PySizer及Heapy等),或者可视化地显示对象之间的引用(如objgraph),从而为发现内存问题提供更直接的证据。本节最后我们再来看看memory_profiler和objgraph这两个工具的使用。
(1)memory_profiler
安装memory_profiler可以使用命令easy_install-U memory_profiler或者pipinstall-U memory_profiler,也可进行源码安装。需要注意的是,在Windows平台上需要先安装依赖包psutil。memory_profiler的使用非常简单,在需要进行内存分析的代码之前用@profile进行装饰,然后运行命令python-m memory_profiler文件名,便可以输出每一行代码的内存使用以及增长情况。
import memory_profiler @profile def fibonacci(n): .......
以代码memory_profiler_test.py为例,输出列分别对应为行号、内存使用情况、内存增长情况以及行所对应的内容。如下所示:
Line # Mem usage Increment Line Contents ================================================ @profile 8.648 MB 0.000 MB def fibonacci(n): 11.500 MB 2.852 MB if n < 0: return -1 11.500 MB 0.000 MB elif n <= 1: 11.500 MB 0.000 MB return 1 11.500 MB 0.000 MB else: 11.500 MB 0.000 MB return fibonacci(n -1) + fibo nacci(n -2)
更多关于memory_profiler的信息可以参考https://pypi.python.org/pypi/memory_profiler。
(2)Objgraph
Objgraph的安装非常简单,可以使用命令pip install objgraph,或者直接从https://pypi.python.org/pypi/objgraph下载进行源码安装。Objgraph的功能大致可以分为以下3类:
统计。如objgraph.count(typename[, objects])表示根据传入的参数显示被gc跟踪的对象的数目;objgraph.show_most_common_types([limit=10, objects])表示显示常用类型对应的对象的数目。
定位和过滤对象。如objgraph.by_type(typename[, objects])表示根据传入的参数显示被gc跟踪的对象信息;objgraph.at(addr)表示根据给定的地址返回对象。
遍历和显示对象图。如objgraph.show_refs(objs[, max_depth=3, extra_ignore=(), filter=None, too_many=10, highlight=None, filename=None, extra_info=None, refcounts=False])表示从对象objs开始显示对象引用关系图;objgraph.show_backrefs(objs[, max_depth=3, extra_ignore=(), filter=None, too_many=10, highlight=None, filename=None, extra_info=None, refcounts=False])表示显示以objs的引用作为结束的对象关系图。
更多关于objgraph使用的API文档参见http://mg.pov.lt/objgraph/objgraph.html。下面来看使用objgraph的两个简单的例子。其中第一个例子生成对象的引用关系图,第二个显示不同类型对象的数目。
图8-3 对象x的引用关系图
1)生成对象x的引用关系图。生成的关系图如图8-3所示。具体代码如下:
>>> import objgraph >>> x = ['a','1',[2,3]] >>> objgraph.show_refs([x],filename='test.png')
2)显示常用类型不同类型对象的数目,限制输出前3行。代码如下:
>>> objgraph.show_most_common_types(limit = 3) wrapper_descriptor 1031 function 975 builtin_function_or_method 615
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论