在调试代码时,您经常面临弄清楚变量何时更改的问题。在没有任何高级工具的情况下,您可以选择使用 print 语句在您期望变量更改时宣布它们。然而,这是一种非常低效的方法,因为变量可能在很多地方更改,并且不断地将它们打印到终端会很嘈杂,而将它们打印到日志文件则会变得笨拙。
这是一个常见问题,但现在有一个简单而强大的工具可以帮助您监控变量:watchpoints。
watchpoint 的概念在 C 和 C++ 调试器中很常见,用于监控内存,但在 Python 中缺乏同等工具。watchpoints
填补了这一空白。
安装
要使用它,您必须首先使用 pip
安装它
$ python3 -m pip install watchpoints
在 Python 中使用 watchpoints
对于您要监控的任何变量,请对其使用 watch 函数。
from watchpoints import watch
a = 0
watch(a)
a = 1
当变量更改时,有关其值的信息将打印到 stdout
====== Watchpoints Triggered ======
Call Stack (most recent call last):
<module> (my_script.py:5):
> a = 1
a:
0
->
1
信息包括
- 变量更改所在的行。
- 调用堆栈。
- 变量的先前/当前值。
它不仅适用于变量本身,还适用于对象更改
from watchpoints import watch
a = []
watch(a)
a = {} # Trigger
a["a"] = 2 # Trigger
当变量 a 被重新赋值时,以及当分配给 a 的对象被更改时,回调都会被触发。
更令人感兴趣的是,监视器不受范围的限制。您可以在任何您想要的地方监视变量/对象,并且无论程序正在执行哪个函数,回调都会被触发。
from watchpoints import watch
def func(var):
var["a"] = 1
a = {}
watch(a)
func(a)
例如,此代码打印
====== Watchpoints Triggered ======
Call Stack (most recent call last):
<module> (my_script.py:8):
> func(a)
func (my_script.py:4):
> var["a"] = 1
a:
{}
->
{'a': 1}
watch 函数可以监控的不仅仅是变量。它还可以监控属性以及字典或列表的元素。
from watchpoints import watch
class MyObj:
def __init__(self):
self.a = 0
obj = MyObj()
d = {"a": 0}
watch(obj.a, d["a"]) # Yes you can do this
obj.a = 1 # Trigger
d["a"] = 1 # Trigger
这可以帮助您缩小到您感兴趣的某些特定对象。
如果您对输出的格式不满意,您可以自定义它。只需定义您自己的回调函数
watch(a, callback=my_callback)
# Or set it globally
watch.config(callback=my_callback)
您甚至可以在触发时启动 pdb
watch.config(pdb=True)
这与 breakpoint() 的行为类似,为您提供类似调试器的体验。
如果您不想在每个文件中都导入该函数,您可以使用 install 函数将其设置为全局
watch.install() # or watch.install("func_name") and use it as func_name()
就我个人而言,我认为 watchpoints 最酷的地方在于其直观的用法。您对某些数据感兴趣吗?只需“watch”它,您就会知道您的变量何时更改。
尝试 watchpoints
我开发并维护了 watchpoints
在 GitHub 上,并已在 Apache 2.0 许可下发布。安装并使用它,当然,始终欢迎贡献。
1 条评论