使用pycallgraph分析python代码函数调用流程以及框架解析
技术背景
在上一篇博客中,我们介绍了使用量子计算模拟器ProjectQ去生成一个随机数,也介绍了随机数的应用场景等。但是有些时候我们希望可以打开这里面实现的原理,去看看在产生随机数的过程中经历了哪些运算,调用了哪些模块。只有梳理清楚这些相关的内容,我们才能够更好的使用这个产生随机数的功能。这里我们就引入一个工具pycallgraph,可以根据执行的代码,给出这些代码背后所封装和调用的所有函数、类的关系图,让我们一起来了解下这个工具的安装和使用方法。
ManjaroLinux平台安装graphviz
首先用pip安装graphviz:
[dechin@dechin-manjarocallgraph]$python3-mpipinstallgraphviz Collectinggraphviz Downloadinggraphviz-0.16-py2.py3-none-any.whl(19kB) Installingcollectedpackages:graphviz Successfullyinstalledgraphviz-0.16
然后再安装pycallgraph,这两者有先后的依赖关系:
[dechin@dechin-manjarocallgraph]$python3-mpipinstallpycallgraph Collectingpycallgraph Downloadingpycallgraph-1.0.1.tar.gz(36kB) Buildingwheelsforcollectedpackages:pycallgraph Buildingwheelforpycallgraph(setup.py)...done Createdwheelforpycallgraph:filename=pycallgraph-1.0.1-py3-none-any.whlsize=35943sha256=d0ee9415d7c268f6964f4a0fd1dc6ec3e039b6bedfe4844de6c1eb8fd0a61389 Storedindirectory:/home/dechin/.cache/pip/wheels/c1/6c/a0/22b61ff9ca89881bb8d030ecd019b84697a39e7b187bc57938 Successfullybuiltpycallgraph Installingcollectedpackages:pycallgraph Successfullyinstalledpycallgraph-1.0.1
用dot-v指令验证一下graphviz是否安装成功:
[dechin@dechin-manjarocallgraph]$dot-v bash:dot:未找到命令
咦?明明参考的正确方法,graphviz咋没有装上呢?经过面向谷歌的编程技术,发现了原来在系统上需要先安装一个graphviz,这里展示的是ManjaroLinux平台的安装方法:
[dechin-manjarocallgraph]#pacman-Sgraphviz 正在解析依赖关系... 正在查找软件包冲突... 软件包(3)gts-0.7.6.121130-2netpbm-10.73.33-1graphviz-2.44.1-6 下载大小:9.74MiB 全部安装大小:24.73MiB ::进行安装吗?[Y/n]Y ::正在获取软件包...... netpbm-10.73.33-1-x86_641867.1KiB6.51MiB/s00:00[####################################]100% gts-0.7.6.121130-2-x86_64211.0KiB12.1MiB/s00:00[####################################]100% 错误:无法从mirrors.ustc.edu.cn:TherequestedURLreturnederror:404获取文件'graphviz-2.44.1-6-x86_64.pkg.tar.zst' 错误:无法从mirrors.tuna.tsinghua.edu.cn:TherequestedURLreturnederror:404获取文件'graphviz-2.44.1-6-x86_64.pkg.tar.zst' 错误:无法从mirrors.huaweicloud.com:TherequestedURLreturnederror:404获取文件'graphviz-2.44.1-6-x86_64.pkg.tar.zst' 错误:无法从mirrors.sjtug.sjtu.edu.cn:TherequestedURLreturnederror:404获取文件'graphviz-2.44.1-6-x86_64.pkg.tar.zst' 错误:无法从mirrors.tuna.tsinghua.edu.cn:TherequestedURLreturnederror:404获取文件'graphviz-2.44.1-6-x86_64.pkg.tar.zst' 错误:无法从mirrors.aliyun.com:TherequestedURLreturnederror:404获取文件'graphviz-2.44.1-6-x86_64.pkg.tar.zst' 警告:无法获取某些文件 错误:无法提交处理(无法获取某些文件) 发生错误,没有软件包被更新。
咦?再一次遇到了问题,配置了这么多镜像源咋都安装不上?再经过一番面向谷歌的编程,发现更新一下源就可以用了:
[dechin-manjarocallgraph]#pacman-Syy ::正在同步软件包数据库... core165.3KiB1968KiB/s00:00[####################################]100% extra1987.0KiB9.11MiB/s00:00[####################################]100% community6.6MiB9.93MiB/s00:01[####################################]100% multilib181.4KiB12.7MiB/s00:00[####################################]100% archlinuxcn1596.1KiB1232KiB/s00:01[####################################]100%
再次尝试安装graphviz:
[dechin-manjarocallgraph]#pacman-Sgraphviz ::Somepackagesshouldbeupgradedfirst... 正在解析依赖关系... 正在查找软件包冲突... 软件包(2)archlinux-keyring-20210110-1manjaro-system-20210217-1 下载大小:0.95MiB 全部安装大小:1.31MiB 净更新大小:0.02MiB ::进行安装吗?[Y/n]Y ::正在获取软件包...... archlinux-keyring-20210110-1-any950.2KiB4.96MiB/s00:00[####################################]100% manjaro-system-20210217-1-any21.4KiB0.00B/s00:00[####################################]100% (2/2)正在检查密钥环里的密钥[####################################]100% (2/2)正在检查软件包完整性[####################################]100% (2/2)正在加载软件包文件[####################################]100% (2/2)正在检查文件冲突[####################################]100% (2/2)正在检查可用存储空间[####################################]100% ::正在处理软件包的变化... (1/2)正在更新archlinux-keyring[####################################]100% ==>正在从archlinux.gpg添加密匙... gpg:公钥CF66D153D884358F在其签名之后的16秒生成 ==>正在本地签名密匙环中的可信密匙... ->正在本地签名密匙AB19265E5D7D20687D303246BA1DFB64FFF979E7... ->正在本地签名密匙DDB867B92AA789C165EEFA799B729B06A680C281... ->正在本地签名密匙0E8B644079F599DFC1DDC3973348882F6AC6A4C2... ->正在本地签名密匙D8AFDDA07A5B6EDFA7D8CCDAD6D055F927843F1C... ->正在本地签名密匙91FFE0700E80619CEB73235CA88E23E377514E00... ==>正在导入拥有者信任值... ==>正在密匙环中禁用已激活密匙... ->正在禁用密匙4A8B17E20B88ACA61860009B5CED81B7C2E5C0D2... ->正在禁用密匙684148BB25B49E986A4944C55184252D824B18E8... ->正在禁用密匙5357F3B111688D88C1D88119FCF2CB179205AC90... ->正在禁用密匙50F33E2E5B0C3D900424ABE89BDCF497A4BBCC7F... ->正在禁用密匙39F880E50E49A4D11341E8F939E4F17F295AFBF4... ->正在禁用密匙F5A361A3A13554B85E57DDDAAF7EF7873CFD4BB6... ->正在禁用密匙40440DC037C05620984379A6761FAD69BA06C6A9... ->正在禁用密匙FB871F0131FEA4FB5A9192B4C8880A6406361833... ->正在禁用密匙487EACC08557AD082088DABA1EB2638FF56C0C53... ->正在禁用密匙76B4192E902C0A52642C63C273B8ED52F1D357C1... ->正在禁用密匙40776A5221EF5AD468A4906D42A1DB15EC133BAD... ->正在禁用密匙0B20CA1931F5DA3A70D0F8D2EA6836E1AB441196... ->正在禁用密匙07DFD3A0BC213FA12EDC217559B3122E2FA915EC... ->正在禁用密匙34C5D94FE7E7913E86DC427E7FB1A3800C84C0A5... ->正在禁用密匙B1F2C889CB2CCB2ADA36D963097D629E437520BD... ->正在禁用密匙D4DE5ABDE2A7287644EAC7E36D1A9E70E19DAA50... ->正在禁用密匙44D4A033AC140143927397D47EFD567D4C7EA887... ->正在禁用密匙8F76BEEA0289F9E1D3E229C05F946DED983D4366... ->正在禁用密匙27FFC4769E19F096D41D9265A04F9397CDFD6BB0... ->正在禁用密匙4FCF887689C41B09506BE8D5F3E1D5C5D30DB0AD... ->正在禁用密匙5A2257D19FF7E1E0E415968CE62F853100F0D0F0... ->正在禁用密匙7FA647CD89891DEDC060287BB9113D1ED21E1A55... ->正在禁用密匙5E7585ADFF106BFFBBA319DC654B877A0864983E... ->正在禁用密匙E7210A59715F6940CF9A4E36A001876699AD6E84... ->正在禁用密匙5559BC1A32B8F76B3FCCD9555FA5E5544F010D48... ->正在禁用密匙BFA1ECFEF1524EE4099CDE971F0CD4921ECAA030... ->正在禁用密匙4D913AECD81726D9A6C74F0ADA6426DD215B37AD... ->正在禁用密匙8840BD07FC24CB7CE394A07CCF7037A4F27FB7DA... ->正在禁用密匙BC1FBE4D2826A0B51E47ED62E2539214C6C11350... ->正在禁用密匙9515D8A8EAB88E49BB65EDBCE6B456CAF15447D5... ->正在禁用密匙779CD2942629B7FA04AB8F172E89012331361F01... ->正在禁用密匙D921CABED130A5690EF1896E81AF739EC0711BF1... ->正在禁用密匙5696C003B0854206450C8E5BE613C09CB4440678... ->正在禁用密匙8CF934E339CAD8ABF342E822E711306E3C4F88BC... ->正在禁用密匙1A60DC44245D06FEF90623D6EEEEE2EEEE2EEEEE... ->正在禁用密匙81D7F8241DB38BC759C80FCE3A726C6170E80477... ->正在禁用密匙63F395DE2D6398BBE458F281F2DBB4931985A992... ->正在禁用密匙65EEFE022108E2B708CBFCF7F9E712E59AF5F22A... ->正在禁用密匙66BD74A036D522F51DD70A3C7F2A16726521E06D... ==>正在更新可信数据库... gpg:下次信任度数据库检查将于2021-03-06进行 (2/2)正在更新manjaro-system[####################################]100% ::正在运行事务后钩子函数... (1/1)ArmingConditionNeedsUpdate... 正在解析依赖关系... 正在查找软件包冲突... 软件包(3)gts-0.7.6.121130-2netpbm-10.73.33-1graphviz-2.46.0-1 下载大小:6.80MiB 全部安装大小:23.32MiB ::进行安装吗?[Y/n]Y ::正在获取软件包...... graphviz-2.46.0-1-x86_646.8MiB7.03MiB/s00:01[####################################]100% (3/3)正在检查密钥环里的密钥[####################################]100% (3/3)正在检查软件包完整性[####################################]100% (3/3)正在加载软件包文件[####################################]100% (3/3)正在检查文件冲突[####################################]100% (3/3)正在检查可用存储空间[####################################]100% ::正在处理软件包的变化... (1/3)正在安装netpbm[####################################]100% (2/3)正在安装gts[####################################]100% (3/3)正在安装graphviz[####################################]100% graphviz的可选依赖 mono:sharpbindings guile:guilebindings lua:luabindings ocaml:ocamlbindings perl:perlbindings[已安装] python:pythonbindings[已安装] r:rbindings tcl:tclbindings[已安装] qt5-base:gvedit[已安装] gtk2:gtkoutputplugin[已安装] xterm:vimdot ::正在运行事务后钩子函数... (1/2)ArmingConditionNeedsUpdate... (2/2)Warnaboutoldperlmodules
Finally还是给我安装成功了,接下来再看看dot指令的执行情况:
[dechin-manjarocallgraph]#dot-v dot-graphvizversion2.46.0(0) libdir="/usr/lib/graphviz" Activatedpluginlibrary:libgvplugin_dot_layout.so.6 Usinglayout:dot:dot_layout Activatedpluginlibrary:libgvplugin_core.so.6 Usingrender:dot:core Usingdevice:dot:dot:core Thepluginconfigurationfile: /usr/lib/graphviz/config6 wassuccessfullyloaded. render:cairodotdot_jsonfiggdjsonjson0mapmppicpovpssvgtkvisiovmlvrmlxdotxdot_json layout:circodotfdpneatonopnop1nop2osagepatchworksfdptwopi textlayout:textlayout device:bmpcanoncmapcmapxcmapx_npdotdot_jsonepsfiggdgd2gifgtkgvicoimapimap_npismapjpejpegjpgjsonjson0mppdfpicplainplain-extpngpovpsps2svgsvgztiftifftkvdxvmlvmlzvrmlwbmpwebpx11xdotxdot1.2xdot1.4xdot_jsonxlib loadimage:(lib)bmpepsgdgd2gificojpejpegjpgpngpssvgwebpxbm
运行示例
这里我们以上一篇博客量子计算模拟器生成随机数中的案例,来测试一下pycallgraph的功能。源代码可以参考源博客地址,这里我们直接展示下更改后的代码:
#random_number.py fromprojectqimportMainEngine fromprojectq.opsimportH,Measure frompycallgraphimportPyCallGraph frompycallgraph.outputimportGraphvizOutput defrandom_number_generator(): eng=MainEngine() qubit=eng.allocate_qubit() H|qubit eng.flush() Measure|qubit random_number=int(qubit) eng.flush(deallocate_qubits=True) returnrandom_number if__name__=='__main__': graphviz=GraphvizOutput() graphviz.output_file='random_number_generator.png' withPyCallGraph(output=graphviz): random_number=random_number_generator() print('Randomnumbergeneratedbyquantumsimulatoris:\ {}'.format(random_number))
其实pycallgraph的使用方法也非常的简单,只需要导入PyCallGraph和GraphvizOutput两个模块,然后把main函数中所有需要运行的正常流程的代码,放到withPyCallGraph(output=graphviz)里面即可。接下来运行该文件:
[dechin@dechin-manjarocallgraph]$python3random_number.py Randomnumbergeneratedbyquantumsimulatoris:0
除了打印输出,我们会发现在当前目录下生成了一个名为random_number_generator.png的图形文件,具体内容打开如下图所示:
补充示例
考虑到上面的运行示例结果比较庞大,这也是一个稍微大一些的软件项目所面临的重大困难。这里为了简明的展示pycallgraph的功能,我们再额外补充一个简单的示例:
#simple_calculation.py frompycallgraphimportPyCallGraph frompycallgraph.outputimportGraphvizOutput defmultiply(a,b): returna*b defplus(a,b): returna+b if__name__=='__main__': graphviz=GraphvizOutput() graphviz.output_file='simple_calculation.png' withPyCallGraph(output=graphviz): a=10 b=2 print('Thevalueofa*b+bis:{}'.format(plus(multiply(a,b),b)))
这个案例的功能,仅仅是把加法和乘法进行了函数的封装,再在main函数中调用,执行结果和pycallgraph生成的图片如下图所示:
[dechin@dechin-manjarocallgraph]$python3simple_calculation.py Thevalueofa*b+bis:22
在这个示例中,我们就可以很清晰的看到这个执行的文件的调用关系,其实就只是调用了multiply和plus两个函数而已。
总结概要
使用pycallgraph这个工具,可以帮助我们更好的入手去分析一个全新的软件包。通过了解各个模块之间的调用关系,我们还可以比较直观的梳理出相关的架构图,带着架构的思维去逐层的分析相应的软件及其实现的方式。
版权声明
本文首发链接为:https://www.cnblogs.com/dechinphy/p/pycallgraph.html
作者ID:DechinPhy
更多原著文章请参考:https://www.cnblogs.com/dechinphy/
到此这篇关于使用pycallgraph分析python代码函数调用流程以及框架解析的文章就介绍到这了,更多相关python代码函数调用内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。