最近写了一个提高 Python 调试效率的工具包 boxx
,目前快完工了, 先分享出来,欢迎大家多提意见,也希望大家能喜欢这个工具。
先从打印开始介绍吧,打印变量是最简单、直接的 debug 方式, 那能不能更简单?
💡 Note: boxx.p
使用了 magic method, p/x
便会打印 x 并返回 x。这样便可以在任何地方打印,比如 例子中的 p/randint(0, 3)
就不需要新建变量便可直接打印
在函数内运行 p()
,便会将函数或 module 内的所有变量名和值一同打印(相当于快捷打印 locals()
)
💡 Note: 在函数内 import boxx.p
和 p()
有相同的效果
许多数情况下, 直接 print
无法获得调试的关键信息。比如变量是有很多属性的对象,numpy
等类型
这时 就必须对变量进行分析, 方式有:
print(x.text, x.code, np.hasinf(x),.np.hasnan(x))
方法 1 每改一次调试代码 都要运行整个代码, 不灵活,操作也繁琐。
方法 2 中进入和退出 Debug console 比较麻烦,Debug console 本身也不太好用(没有自动补全功能)
boxx.g
提供了一种新的方式,通过 g.name
可以将变量传到当前的 Python 交互终端
变量传到 Python 终端后,就能对变量进行全面分析了,比如 使用tree
,what
来分析
💡 Note:
gg
的意思是 to Global and log
, 和 g
的用法一样, 但 gg
会在传输的同时打印变量.在函数内运行 g()
,便会将函数 (或 module) 内的所有变量一同传到当前的 Python 交互终端
这样 任何错误都可以在终端中复现和分析了。当然, 注意不要覆盖重要的全局变量。
💡 Note: 在函数内 import boxx.g
和 g()
有相同的效果
在实际开发调试中, 函数或 module 内可能含有非常多的变量 但我们只对几个变量感兴趣, with p
, with g
, with gg
可以使操作只作用于几个感兴趣的变量,只需把变量放入 with
结构中即可 :
💡 Note:
with p
, with g
, with gg
只作用于在 with
结构中进行赋值操作的变量.with
前存在于 locals()
中, 同时 id(变量)
没有变化 , with
结构可能无法检测到该变量.总结一下,boxx
的调试工具可以汇总为一个表
💡 Note:
locals()
指 作用于函数或 module 内的所有变量locals()
_2: 当 boxx
未导入时, import boxx.{操作}
能等价于 from boxx import {操作};{操作}()
在学习新框架或适配大佬代码时,经常会使用 print(x)
, dir(x)
, help(x)
, type(x)
来了解某个变量的各方面的信息 (变量可能是 值 /function/class/module 等),于是我写了一个 boox.what(x)
来全面了解"what is x
?":
💡 Note: what(x)
通过打印 x
自己及x
的 文档, 父类继承关系, 内部结构 及 所有属性 来全面了解 x
. 是 help(x)
的补充.
说了这么多调试 再说一下性能调优
测试代码性能时,计时很常用, 我写了一个方便的计时工具boxx.timeit
将想要计时的代码块放入 with timeit():
中就可以计时了:
此外 SnakeViz
是一个很棒的性能分析工具,SnakeViz
能够通过 cProfile
文件,来统计代码的函数调用情况,并可视化出代码的 火焰图。但是, 先生成 cProfile
文件,再运行 SnakeViz
的流程非常繁琐,我把这一套操作封装成了 boxx.performance
来简化流程:
💡 Note: performance
也支持字符串形式的 Python 代码.
在进行密集运算和处理时 得写多进程的 Python 代码 来榨干 CPU 的每一个线程获得加速。但我觉得 Python 多进程的几个范式都不够方便,我参照 map
的思想和用法把多进程操作封装成 boxx.mapmp
函数(意思是"Map for Mulit Processing"). mapmp
和 map
有一样的用法, 只需把 map
替换为 mapmp
即可获得多进程加速:
💡 Note:
mapmp
的 pool 参数来控制进程数目,默认为 CPU 线程数目.mapmp
的 printfreq 参数能解决这个问题.map
一样,mapmp
支持将多个参数输入函数,如mapmp(add, list_1, list_2)
对于网络爬虫等高 IO 操作,boxx
还有个多线程版本的 map
-- mapmt
(意思是 "Map for Mulit Threading")。mapmt
用法和 mapmp
一样, 但没有多进程的诸多限制。
在开发和适配代码时,会遇到一些复杂的 dict,list。boxx.tree
可以直观地展示复杂结构。
大致就介绍这些 boxx
的这些功能吧,欢迎大家多提意见!
GitHub 主页:https://github.com/DIYer22/boxx(内含有更多说明)
教程:boxx
的教程是一个可执行的在线 Notebook。 也就是说,无需下载和运行任何代码,只需浏览器点击下面的链接,就可以在线执行 Notebook 教程中的代码块。
=> 可直接执行的在线教程
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.