傻大方


首页 > 潮·科技 > >

求你了,别再用 print 调试代码了



按关键词阅读:

对于每个程序开发者来说 , 调试几乎是必备技能 。 代码写到一半卡住了 , 不知道这个函数执行完的返回结果是怎样的?调试一下看看代码运行到一半报错了 , 什么情况?怎么跟预期的不一样?调试一下看看调试的方法多种多样 , 不同的调试方法适合不同的场景和人群 。

  • 如果你是刚接触编程的小萌新 , 对很多工具的使用还不是很熟练 , 那么 print 和 log 大法好
  • 如果你在本地(Win或者Mac)电脑上开发 , 那么 IDE 的图形化界面调试无疑是最适合的;
  • 如果你在服务器上排查BUG , 那么使用 PDB 进行无图形界面的调试应该是首选 。
  • 如果你要在本地进行开发 , 但是项目的进行需要依赖复杂的服务器环境 , 那么可以了解下 PyCharm 的远程调试 。
除了以上 , 今天再给你介绍一款非常好用的调试工具 , 它能在一些场景下 , 大幅度提高调试的效率 ,那就是 PySnooper , 它在 Github 上已经收到了 13k 的 star , 获得大家的一致好评 。 有了这个工具后 , 就算是小萌新也可以直接无门槛上手 , 从此与 print 说再见~
1. 快速安装执行下面这些命令进行安装 PySnooper
$ python3 -m pip install pysnooper
# 或者
$ conda install -c conda-forge pysnooper
# 或者
$ yay -S python-pysnooper
2. 简单案例下面这段代码 , 定义了一个 demo_func 的函数 , 在里面生成一个 profile 的字典变量 , 然后去更新它 , 最后返回 。 代码本身没有什么实际意义 , 但是用来演示 PySnooper 已经足够 。
import pysnooper
@pysnooper.snoop
def demo_func:
profile = {}
profile["name"] = "写代码的明哥"
profile["age"] = 27
profile["gender"] = "male"
return profile
def main:
profile = demo_func
main
现在我使用终端命令行的方式来运行它
[root@iswbm ~]# python3 demo.py
Source path:... demo.py
17:52:49.624943 call 4 def demo_func:
17:52:49.625124 line 5 profile = {}
【求你了,别再用 print 调试代码了】New var:....... profile = {}
17:52:49.625156 line 6 profile["name"] = "写代码的明哥"
Modified var:.. profile = {'name': '写代码的明哥'}
17:52:49.625207 line 7 profile["age"] = 27
Modified var:.. profile = {'name': '写代码的明哥', 'age': 27}
17:52:49.625254 line 8 profile["gender"] = "male"
Modified var:.. profile = {'name': '写代码的明哥', 'age': 27, 'gender': 'male'}
17:52:49.625306 line 10 return profile
17:52:49.625344 return 10 return profile
Return value:.. {'name': '写代码的明哥', 'age': 27, 'gender': 'male'}
Elapsed time: 00:00:00.000486
可以看到 PySnooper 把函数运行的过程全部记录了下来 , 包括:
  • 代码的片段、行号等信息 , 以及每一行代码是何时调用的?
  • 函数内局部变量的值如何变化的?何时新增了变量 , 何时修改了变量 。
  • 函数的返回值是什么?
  • 运行函数消耗了多少时间?
而作为开发者 , 要得到这些如此详细的调试信息 , 你需要做的非常简单 , 只要给你想要调试的函数上带上一顶帽子(装饰器) -- @pysnooper.snoop即可 。
3. 详细使用2.1 重定向到日志文件@pysnooper.snoop不加任何参数时 , 会默认将调试的信息输出到标准输出 。 对于单次调试就能解决的 BUG, 这样没有什么问题 , 但是有一些 BUG 只有在特定的场景下才会出现 , 需要你把程序放在后面跑个一段时间才能复现 。 这种情况下 , 你可以将调试信息重定向输出到某一日志文件中 , 方便追溯排查 。
@pysnooper.snoop(output='/var/log/debug.log')
def demo_func:
...
2.2 跟踪非局部变量值PySnooper 是以函数为单位进行调试的 , 它默认只会跟踪函数体内的局部变量 , 若想跟踪全局变量 , 可以给 pysnooper.snoop加上watch参数
out = {"foo": "bar"}
@pysnooper.snoop(watch=('out["foo"]'))
def demo_func:
...
如此一来 , PySnooper 会在 out["foo"]值有变化时 , 也将其打印出来
求你了,别再用 print 调试代码了文章插图
watch 参数 , 接收一个可迭代对象(可以是list 或者 tuple) , 里面的元素为字符串表达式 , 什么意思呢?看下面例子就知道了
@pysnooper.snoop(watch=('out["foo"]', 'foo.bar', 'self.foo["bar"]'))
def demo_func:
...
watch相对的 , pysnooper.snoop还可以接收一个函数watch_explode , 表示除了这几个参数外的其他所有全局变量都监控 。


稿源:(未知)

【傻大方】网址:http://www.shadafang.com/c/111J2J562020.html

标题:求你了,别再用 print 调试代码了


上一篇:《Python中神奇的第三方库:Faker》

下一篇:Jupyter Notebook & Lab快捷键大全