pycallgraph 追踪Python函数内部调用
GitHub上好代码真的是太多了,名副其实的一个宝藏。但是最近自己也反思了一下,为什么别人的代码看起来那么的费劲。很多时候还不得要领,博主的笨方法就是先看下代码的结构,目录。然后就从程序的入口出发了,一步步的往底层去追溯,但是因为忒懒,也没有超大的临时记忆空间,于是代码跟着跟着就跑偏了,这也是看别人代码的时候效率不高的主要原因。
幸运的是,发现了一款神器,pycallgraph,其作用就是追踪函数的相互调用的情况,如此一来,对每个函数的的追踪将一览无余。
安装
安装这个库是比较简单的,但是安装好了是不能用的。
因为还需要一个图形库的依赖(graphviz), 这个依赖是著名的贝尔实验室的一位大牛写的一个命令行下的作图工具库。超赞。
安装pycallgraph
pip install pycallgraph
安装依赖
graphviz2.38 画图库下载链接为:
下载完之后,为了不出现之前的那个command命令实效。我们还得将graphviz的path添加到电脑的系统变量中。
具体做法:
系统属性->高级设置->环境变量->path->记得环境变量之间用英文的;号分隔开
使用
配置好了上面的步骤之后,就可以正式的使用pycallgraph咯。为了方便演示,这里写了一段简单的脚本。
待测脚本
# downloadmusic.py
# 之前适用于下载QQ音乐的,这里的作用就是下载一张图片
import urllib2
import threading
def download(url, path):
data = urllib2.urlopen(url).read()
open(path, 'wb').write(data)
print "success!"
然后我们就可以使用pycallgraph来完成简单的追踪过程了。
追踪脚本
# 追踪代码
# coding: utf8
from pycallgraph import PyCallGraph
from pycallgraph import Config
from pycallgraph.output import GraphvizOutput
from downloadmusic import *
graphviz = GraphvizOutput(output_file=r'./trace_detail.png')
with PyCallGraph(output=graphviz):
download('http://www.baidu.com/img/bd_logo1.png', r'./baidu.png')
追踪结果
运行完脚本后,此文件夹中的细节如下:
F:\temp\downloadmusic>tree /F
卷 娱乐 的文件夹 PATH 列表
卷序列号为 0000-4823
F:.
baidu.png
calldetails.py
downloadmusic.py
downloadmusic.pyc
trace_detail.png
没有子文件夹
在成功的下载了一张百度的logo照片之后,我们不难发现,多了一个叫trace_detail.png 的文件。
如下:
是不是感觉还不赖呢?函数之间的依赖关系,调用情况都可以得到很好的追溯。
高级篇
所谓高级,就是附加了点小情况而已。无非加个过滤条件,控制一下函数调用的追踪深度。
隐藏私密函数
如题,隐藏那些不想看到的函数的名称,这一点在某些情况下还是很好用的。
rom pycallgraph import PyCallGraph
from pycallgraph import Config
from pycallgraph import GlobbingFilter
from pycallgraph.output import GraphvizOutput
from banana import Banana
config = Config()
config.trace_filter = GlobbingFilter(exclude=[
'pycallgraph.*',
'*.secret_function',
])
graphviz = GraphvizOutput(output_file='filter_exclude.png')
with PyCallGraph(output=graphviz, config=config):
banana = Banana()
banana.eat()
控制最大追踪深度
这一点也很好理解了吧,待会看完图就更加清晰了。
from pycallgraph import PyCallGraph
from pycallgraph import Config
from pycallgraph.output import GraphvizOutput
from banana import Banana
config = Config(max_depth=1)
graphviz = GraphvizOutput(output_file='filter_max_depth.png')
with PyCallGraph(output=graphviz, config=config):
banana = Banana()
banana.eat()
总结
这次的文章没什么技术含量,但是确实很实用的一篇介绍性的文章。下次读代码遇到瓶颈的时候,不妨来尝试一把这个工具。相信会让你眼前一亮的。
pycallgraph 追踪Python函数内部调用的更多相关文章
- 你好,C++(27)在一个函数内部调用它自己本身 5.1.5 函数的递归调用
5.1.5 函数的递归调用 在函数调用中,通常我们都是在一个函数中调用另外一个函数,以此来完成其中的某部分功能.例如,我们在main()主函数中调用PowerSum()函数来计算两个数的平方和,而在P ...
- python 函数的调用 和执行 小知识
1.符号表 执行一个函数会引入一个用于函数的局部变量的新符号表. 更确切地说, 函数中的所有的赋值都是将值存储在局部符号表: 而变量引用首先查找局部符号表, 然后是上层函数的局部符号表, 然后是全局符 ...
- python函数及调用
python的函数是一段重复多次可调用的代码,依据python的函数,我们可以利用函数式的编程,来减少代码的重复. 在本章节中,详细的介绍python的函数,以及python的函数式编程的与众不同,函 ...
- Python函数递归调用
函数的递归调用: 是函数嵌套调用的一种特殊形式 具体是指: 在调用一个函数的过程中又直接或间接地调用到了本身 # 直接调用本身 def func(): print('我是func') func() f ...
- python类内部调用自己的成员函数必须加self
class A: def a(self): print("hello world") def b(self): return self.a() 上面的self.a()中self是不 ...
- python函数之调用函数
调用函数 python中内置了许多函数,我们可以直接调用,但需要注意的是参数的个数和类型一定要和函数一致,有时候不一致时,可以进行数据类型转换 1.abs()函数[求绝对值的函数,只接受一个参数] # ...
- python函数进阶(函数参数、返回值、递归函数)
函数进阶 目标 函数参数和返回值的作用 函数的返回值 进阶 函数的参数 进阶 递归函数 01. 函数参数和返回值的作用 函数根据 有没有参数 以及 有没有返回值,可以 相互组合,一共有 4 种 组合形 ...
- python函数(二)
python函数(二) 变量的作用域 1.局部变量与全局变量 在函数内创建的变量被称为局部变量,这类变量的生命周期与函数相同,当函数执行完毕时,变量也就随之消失. 此类变量只能在函数内部调用,函数外不 ...
- python函数进阶
知识内容: 1.函数即变量 2.嵌套函数 3.lambda表达式与匿名函数 4.递归函数 5.函数式编程简介 6.高阶函数与闭包 一.函数即变量 1.变量的本质 声明一个变量,在python里本质上讲 ...
随机推荐
- 0307-关于html
html最主要的三点: 1.标签的写法.用法 <标签名 属性名1="属性值1" 属性名2="属性值2">内容</标签名> 比如:< ...
- Docker配置加速器
我们国内使用官方Docker Hub仓库实在是太慢了,很影响效率 使用命令编辑文件: vim /etc/docker/daemon.json 加入下面的数据: docker-cn镜像: { " ...
- [LeetCode] Min Cost Climbing Stairs 爬楼梯的最小损失
On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed). Once you pay ...
- [LeetCode] Next Greater Element III 下一个较大的元素之三
Given a positive 32-bit integer n, you need to find the smallest 32-bit integer which has exactly th ...
- 基于线程池的多线程售票demo2.0(原创)
继上回基于线程池的多线程售票demo,具体链接: http://www.cnblogs.com/xifenglou/p/8807323.html以上算是单机版的实现,特别使用了redis 实现分布式锁 ...
- 【Python3.6+Django2.0+Xadmin2.0系列教程之二】学生信息管理系统(入门篇)
上一篇我们已经创建好了一个Xadmin的基础项目,现在我们将在此基础上构建一个同样很基础的学生信息管理系统. 一.创建模型 模型是表示我们的数据库表或集合类,并且其中所述类的每个属性是表或集合的字段, ...
- OpenShift实战(六):OpenShift日志监控EFK
1.镜像下载 为了防止安装过程中由于镜像下载缓慢导致自动部署失败,所以首先提前下载好EFK镜像. docker pull openshift/origin-logging-fluentd docker ...
- AtCoder Grand Contest 021 D - Reversed LCS
Description Takahashi has decided to give a string to his mother. The value of a string T is the len ...
- [HOJ2634] How to earn more 最大权闭合子图
Xiao Ming is an expert in computer science and technology, so he can get a lot of projects every mon ...
- Python【第五课】迭代器,生成器,数据序列化
本节内容 列表生成式,生成器,迭代器 Json & pickle 数据序列化 1.列表生成式,生成器,迭代器 1.1 列表生成式 列表生成式?不就是生成个列表的表达式,恩~~~ 差不多. 一般 ...