当前位置: 首页 > 工具软件 > Watchpoints > 使用案例 >

tracer使用python_Python+watchpoints!超轻量级debug利器

松英喆
2023-12-01

大家在debug Python的时候有没有遇到如下的情况:我知道某个变量出了问题,但是我不知道它是在哪里被修改的,于是只好在每一个可能修改它的地方都打个print。

在gdb里,有一个很好用的feature叫watchpoints,和监控pc的breakpoint对应的,它可以监控一块内存,当这块内存被修改的时候中断程序。

然而Python自带的pdb里并没有这个功能,于是我花了一些时间做了一个功能类似的库,watchpoints!

我的核心思路是,打造一个超轻量级,极其符合人类直觉的debug工具。为此用了不少的黑科技。

从最简单的开始吧,假设我们有一个变量a

a = 0

我们希望每次a产生变化的时候,都打印出来a之前的值,和变化之后的值,以及它变化的位置。

from watchpoints import watch

a = 0

watch(a)

a = 1

是的,没有比这更符合人类直觉的用法了,我想观察a,我就watch(a)

运行之后得到

> (my_script.py:4):

> a = 1

a:

0

->

1

在程序的第四行,我们把变量a从0变成了1。

不光是单纯的variable,watchpoints还支持attribute和index。比如我就想观察某一个dict里的某一个key

from watchpoints import watch

d = {"a": 0, "b": 0}

watch(d["a"])

d["a"] = 1

d["b"] = 1

运行后得到

> (my_script.py:4):

> d["a"] = 1

d["a"]:

0

->

1

d["a"]的变化被记录下来了,而d["b"]没有。

基本上你能想到的符合人类直觉的用法,都可以直接watch(),在绝大部分情况下,都会给你想要的结果。

而和一些其他的local variable monitor工具(比如pysnooper)不同的是,watchpoints并不会被scope局限。

from watchpoints import watch

def generate():

a = []

watch(a)

return a

def change(l):

l.append(1)

lst = generate()

change(lst)

在任何一个地方我们都可以watch()一个变量(object),在scope之外的修改也会被捕捉到。

> change (my_script.py:8):

> l.append(1)

a:

[]

->

[1]

有的时候,我们不光是希望捕捉变化,我们希望捕捉变化到某个状态的时刻。比如有一个值理论上是非负整数,但是我发现它变成负数了。我们可以通过conditional callback来完成这件事。

from watchpoints import watch, unwatch

class MyObj:

def __init__(self):

self.val = 0

obj = MyObj()

watch(obj.val, when=lambda x: x < 0)

for i in range(10):

obj.val += 1

obj.val = -1 # oops

这种情况下,不满足when条件的变化就不会被记录,只有最后一行会触发

> (my_script.py:11):

> obj.val = -1 # oops

obj.val:

10

->

-1

当然,一定会有更高端的用户觉得,打印到屏幕是个并不理想的解决方案,放心,watchpoints提供了很简单的自定义callback,可以让你随心所欲地利用watch的强大功能。对输出的format不满意?希望log到文件?希望每次变化的时候改变其他的变量?都可以做到。

watch(a, callback=callback) # customized callback per variable

watch.config(callback=callback) # global customized callback

喜欢pdb的用户也不要难过,watch()完全可以做到类似breakpoint()的效果,在变量修改的时候调出pdb。只需要

watch.config(pdb=True)

watchpoints还有一些其他的小功能,在这里就不一一阐述了,感兴趣的小伙伴可以去github看一下,基本功能全部列出来了。https://github.com/gaogaotiantian/watchpoints​github.com

这是在VizTracer之后我的另一个开源项目,依然是debugging领域的。和VizTracer不同的是,watchpoints甚至更加轻了,使用方式友善到爆炸,学习曲线几乎看不见。纯Python的实现,全平台支持。

在未来的时间里,我会给watchpoints增加更多的有价值的功能,同时也不会扔下VizTracer的开发和维护,希望给大家带来更给力的debug工具!

 类似资料: