前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python代码调试方法

Python代码调试方法

作者头像
用户9925864
发布2022-07-27 08:19:23
4680
发布2022-07-27 08:19:23
举报
文章被收录于专栏:算法工程师的学习日志

对于每个程序开发者来说,调试几乎是必备技能。常用Pycharm编辑器里的方法有Print大法、log大法,但缺少类似Matlab的变量区,给代码调试带来不便,特别是在有函数的情况下,变量无法实时查看。


1、Python Console

在Pycharm编辑器里面有个Python Console,可以查看变量变化,但对于函数变量难调试。


2、PySnooper

安利一款非常好用的调试工具,它能在一些场景下,大幅度提高调试的效率, 那就是 PySnooper

2.1、快速安装

执行下面这些命令进行安装 PySnooper

代码语言:javascript
复制
pip install pysnooper

2.2、简单案例

下面这段代码,定义了一个 test 的函数,在里面生成一个 person 的字典变量,然后去更新它,最后返回。

代码语言:javascript
复制
import pysnooper


@pysnooper.snoop()
def test():
    person = {}
    person["name"] = "domi"
    person["age"] = 28
    person["gender"] = "male"
    return person


def main():
     author = test()


main()

‍输出结果

代码语言:javascript
复制
21:25:21.875841 call         5 def test():
21:25:21.875841 line         6     person = {}
New var:....... person = {}
21:25:21.875841 line         7     person["name"] = "domi"
Modified var:.. person = {'name': 'domi'}
21:25:21.876840 line         8     person["age"] = 28
Modified var:.. person = {'name': 'domi', 'age': 28}
21:25:21.876840 line         9     person["gender"] = "male"
Modified var:.. person = {'name': 'domi', 'age': 28, 'gender': 'male'}
21:25:21.876840 line        10     return person
21:25:21.876840 return      10     return person
Return value:.. {'name': 'domi', 'age': 28, 'gender': 'male'}
Elapsed time: 00:00:00.000999

PySnooper 把函数运行的过程全部记录了下来,包括:

  • 代码的片段、行号等信息,以及每一行代码是何时调用的?
  • 函数内局部变量的值如何变化的?何时新增了变量,何时修改了变量。
  • 函数的返回值是什么?
  • 运行函数消耗了多少时间?

2.3、重定向到日志文件

@pysnooper.snoop() 不加任何参数时,会默认将调试的信息输出到标准输出。对于单次调试就能解决的 BUG ,这样没有什么问题,但是有一些 BUG 只有在特定的场景下才会出现,需要你把程序放在后面跑个一段时间才能复现。这种情况下,你可以将调试信息重定向输出到某一日志文件中,方便追溯排查。

代码语言:javascript
复制
@pysnooper.snoop(output='./debug.log')
def test():

2.4、跟踪非局部变量值

PySnooper 是以函数为单位进行调试的,它默认只会跟踪函数体内的局部变量,若想跟踪全局变量,可以给 pysnooper.snoop() 加上 watch 参数

代码语言:javascript
复制
out = {"foo": "bar"}
@pysnooper.snoop(watch=('out["foo"]'))
def test():
    person = {}
    person["name"] = "domi"
    person["age"] = 28
    person["gender"] = "male"
    out["foo"] += 'test'
    return person

2.5、设置跟踪函数的深度

当你使用 PySnooper 调试某个函数时,若该函数中还调用了其他函数,PySnooper 是不会傻傻的跟踪进去的。如果你想继续跟踪该函数中调用的其他函数,可以通过指定 depth 参数来设置跟踪深度(不指定的话默认为 1)。

代码语言:javascript
复制
@pysnooper.snoop()
def test():
    person = {}
    person["name"] = "domi"
    person["age"] = 28
    person["gender"] = "male"
    c = test1()
    return person


def test1():
    a = 1
    b = 2
    return a + b
代码语言:javascript
复制
@pysnooper.snoop(depth=2)

2.6、设置调试日志的前缀

当你在使用 PySnooper 跟踪多个函数时,调试的日志会显得杂乱无章,不方便查看。在这种情况下,PySnooper 提供了一个参数,方便你为不同的函数设置不同的标志,方便你在查看日志时进行区分。

代码语言:javascript
复制
@pysnooper.snoop(output="./debug.log", prefix="test: ")
def test():
    person = {}
    person["name"] = "domi"
    person["age"] = 28
    person["gender"] = "male"
    c = test1()
    return person


@pysnooper.snoop(output="./debug.log", prefix="test1: ")
def test1():
    a = 1
    b = 2
    return a + b

2.7、支持多线程调试模式

PySnooper 同样支持多线程的调试,通过设置参数 thread_info=True,它就会在日志中打印出是在哪个线程对变量进行的修改。

代码语言:javascript
复制
@pysnooper.snoop(thread_info=True)
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-11-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 算法工程师的学习日志 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档