前言

PyCharm Debug 可以帮助开发者在代码运行时进行实时的调试和错误排查,提高代码开发效率和代码质量。当然也可以对源码进行断点调试,领略源码的魅力。

具体操作步骤

准备一段代码

让我们来举个简单的栗子
这段代码主要作用,循环 range 里面的值并调用自定义的 add 方法将返回的结果打印

def add(num1, num2):
    return num1 + num2

if __name__ == '__main__':

    for num in range(1, 3):
        result = add(num, num + 1)
        print("result {}".format(result))

放置断点

在你想放置断点的处点击如图所示:
点击后会有一个实心的红点,此刻你的断点已经放置成功啦

启动 debug

启动 debug 的方式有三种:

第一种方法:点击 main 方法旁边的绿色图标 

第二种方法:选择需要 debug 的文件,在点击 “小乌龟” 图标

第三种方法:在代码空白处右键→选择 “debug”

以上 3 种方式,大家根据自己的习惯自行选择

调试界面详解

写到这里,简单的解释下,断点调试的意思就是程序在执行到你打断点位置时,暂时挂起(你可以理解为是等待)此时你可以看到你之前运行程序的一些变量参数等信息

启动调试后我们会看到这样一个界面,这个界面元素有点多,我们慢慢的分析下,先看整体,分为 3 个区域:

红色部分:最为重要主要是控制调试代码的走向

黄色部分:主要是查看变量信息

蓝色部分:主要是纪录程序运行时的一些调用方法的堆栈信息的纪录,蓝色框可以看出方法被调用的轨迹,每次调用一个方法时,都会在堆栈的顶部添加一个新的帧(这里可以理解为是一行),当一个方法的执行完成时,相应的帧将从堆栈中移除(以后进先出的方式),在文章的后面会有具体的解释,这里可以不用过多的关注

我们先重点介绍下红色部分: ​

我用的 Pycharm 版本比较老有的图标会和最新的版本有点出入但是不影响使用(如果大家看不清可以点击图片进行预览)

具体例子展示

示例一:入门级别

启动 debug 调试后,当线条变成蓝色的时候表示程序正在运行到这一行,大家注意上面会有一行灰色的字,这个表示 num 的值当前为 1

点击 step  into(进入方法)
我们会看到程序 跳转到了 add 这个方法当前 num1=1;num2=2,并且 Frames 添加了一行

点击 step over(按行执行代码)
我们看到蓝色的光标又回到了 main 函数 ,并且 Frames 少了一行说明 add 方法已经执行完毕

点击 step over(按行执行代码)
获取了 result 值=3,此时控制台并没有输出内容


​点击 step over(按行执行代码)
控制台输出了内容 “result 3”,蓝色的光标重新移到 for 循环,准备下一轮的循环

点击 step over(按行执行代码)
此刻 num=2,进入下一轮的循环

点击 step over(按行执行代码)
此刻 num=2 ,result=5,注意这个时候因为我们没有进入方法所以旁边的 Frames 并没有新增一行

点击 step over(按行执行代码)
此刻控制台输出内容 “result 5”,蓝色光标移到 for 循环准备下一次的循环

点击 step over(按行执行代码)
因下一次的 num=3 不满足 for 循环的要求循环结束,整个 debug 的调试也随之结束

示例二:源码调试

以下代码是连接手机,获取并打印手机的 deviceInfo 信息,这里我们主要是想通过 debug 看下 pyhon 端是如何发送 HTTP 请求给手机端和手机端返回的信息

前置条件

准备代码

import uiautomator2 as u2

if __name__ == '__main__':
    device = u2.connect()
    print(device.info)

源码分析添加断点

通过跟踪源码我们可以看到 info() 方法先调用的 jsonrpc() 这个方法,在初始化类的时候会调用call方法,在 call 方法中会调用_jsonrpc_retry_call 这个方法于是我们把断点打在了这里,看下是否会走到这个方法,我们继续往下看

_jsonrpc_retry_call 这个方法又调用了_jsonrpc_call 这个方法,在仔细的看下这个方法我们主要是想得到他的请求体和返回体所以我们把断点打在了这里

开启调试

蓝色框内我们可以看到是方法的调用栈,红色框框部分是正在运行的地方,证实了我们的猜想是对的,我们直接跳到下一个断点看看

点击 resume program(跳到下一个断点处)
蓝色部分新增了一行表示又调用了一个_jsonrpc_call 方法和我们的猜想一样,接下来我们看下 res 的返回,我们的目的是为了看请求体和响应结果的,仔细看我们看到了一个 request 的请求对象我们展开看看

红色框部分不就是我们想找的信息嘛,找到了请求体之后我们在看看返回结果,继续找

在 request 的后面还有一个 text 的参数,这不就是我们要找的返回内容嘛,因为单行展示有限我们可以通过点击 “View” 来查看详情,获取更完善的信息

大功告成!我们可以结束断点啦!点击 stop"mian"程序运行结束

清除断点

忽略断点

如果我们想保留断点位置,又不想让程序执行的时候在断点处挂起,这个时候我们可以点击 enbaled 让断点不生效

如果我们想忽略所有断点可以点击 “Mute breakpoints”

总结

类库的 debug 的调试会比自己写的代码的调试要复杂点,如果大家想知道源码的方法调用,可以自己先走读下代码在觉得会走的地方打断点,在 debug 进行验证,也可以直接 step over(按行执行代码)但是这样会比较费时间,根据大家自己的选择,debug 的调试刚开始的时候会比较不顺畅当你用多了,就自然懂了。

更多 debug 调试内容可以参考官方文档:https://www.jetbrains.com/help/pycharm/debugging-code.html


↙↙↙阅读原文可查看相关链接,并与作者交流