使用Python中PDB模块中的命令来调试Python代码的教程

news/2023/12/5 23:11:28

这篇文章主要介绍了使用Python中PDB模块中的命令来调试Python代码的教程,包括设置断点来修改代码等、对于Python团队项目工作有一定帮助,需要的朋友可以参考下

你有多少次陷入不得不更改别人代码的境地?如果你是一个开发团队的一员,那么你遇到上述境地的次数比你想要的还要多。然而,Python中有一个整洁的调试特性(像其他大多数语言一样),在这种情况下使用非常方便。本文是一篇快速教程,希望它能让你的编码生活更加容易。
1. 一个混乱的程序

出于本教程的目的,让我们研究一下下面的简单程序。

这个程序接收两个命令行参数,然后执行加法和减法操作。

(假设用户输入的是有效值,因此代码中我们没有进行错误处理。)
 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

import sys

def add(num1=0, num2=0):

  return int(num1) + int(num2)

def sub(num1=0, num2=0):

  return int(num1) - int(num2)

def main():

  #Assuming our inputs are valid numbers

  print sys.argv

  addition = add(sys.argv[1], sys.argv[2])

  print addition

  subtraction = sub(sys.argv[1], sys.argv[2])

  print subtraction

if __name__ == '__main__':

  main()

2. PDB

Python提供了一个有用的模块PDB,它实际上是一个交互式源代码调试器。

你需要下面的两行代码来使用此模块。
 

1

2

import pdb

pdb.set_trace()

看一下我们修改过的程序,里面包含了一些断点。
 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

import pdb

import sys

def add(num1=0, num2=0):

  return int(num1) + int(num2)

def sub(num1=0, num2=0):

  return int(num1) - int(num2)

def main():

  #Assuming our inputs are valid numbers

  print sys.argv

  pdb.set_trace() # <-- Break point added here

  addition = add(sys.argv[1], sys.argv[2])

  print addition

  subtraction = sub(sys.argv[1], sys.argv[2])

  print subtraction

if __name__ == '__main__':

  main()

3. 程序执行触发调试器

一旦你设置好断点以后,你就可以像平时一样执行程序。
 

1

python debugger.py 1 2

程序将会在遇到的第一个断点处停止执行。
 

1

2

3

4

['debugger.py']

> /Users/someuser/debugger.py(15)main()

-> addition = add(sys.argv[1], sys.argv[2])

(Pdb)

我们在第14行设置了一个断点,所以我们能看到将要执行的下一行是第15行。可以看到,在执行到第15行之前程序已经停止。

在这里我们有几个选项,让我们在下面步骤中看看一些调试指令。
4. 下一行->n

在你的调试器提示中,输入n运行到下一行。
 

1

2

3

4

5

> /Users/someuser/debugger.py(14)main()

-> addition = add(sys.argv[1], sys.argv[2])

(Pdb) n

> /Users/someuser/debugger.py(15)main()

-> print addition

这会执行当前行代码,并准备执行下一行。

我们可以使用n来逐行执行整个程序,但这其实没有什么用处。

可能你已经看到,PDB实际上并没有进入我们的add函数中。下面,就让我们看看其他几个令调试更加有趣的选项。

    注意:
    一个更酷的特性是你可以单击回车键来执行以前的命令(在本例中只要指令n)。

5. 打印->p

下面,我们再次开始调试程序。(你可以通过单击c使PDB跳到末尾或者直到下一个断点,因为程序中我们并没有其他的断点了,所有程序将会执行完成。)
 

1

2

3

4

['debugger.py', '1', '2']

> /Users/someuser/debugger.py(14)main()

-> addition = add(sys.argv[1], sys.argv[2])

(Pdb)

现在,如果我们想知道sys.argv中包含什么内容,我们可以输入以下内容:
 

1

2

3

4

5

6

-> addition = add(sys.argv[1], sys.argv[2])

(Pdb) p sys.argv

['debugger.py', '1', '2']

(Pdb) p sys.argv[1]

'1'

(Pdb)

使用这种方法可以相当方便地查看变量中实际存储着什么值。

现在我们将进入加法函数内部。
6. 单步->s

我们可以使用“s”进入加法函数内部。

1

2

3

4

5

6

7

8

(Pdb) s

--Call--

> /Users/someuser/debugger.py(4)add()

-> def add(num1=0, num2=0):

(Pdb) n

> /Users/someuser/debugger.py(5)add()

-> return int(num1) + int(num2)

(Pdb)

这将把我们带入加法函数的内部,现在我们可以在加法函数内部使用n、p和其他的操作指令。

此时单击“r”将会把我们带到前面进入函数的返回语句。

如果你想快速跳转到一个函数的结尾处,那么这个指令将很有用。
7. 动态添加断点- > b

前面,在程序运行之前,我们使用pdb.set_trace()设置了一个断点。

不过,经常在调试会话已经开始之后,我们想要在程序中特定的地方添加断点。

这里我们就可以使用选项“b”来实现这种目的。

我们重新开始执行程序。
 

1

2

3

4

['debugger.py', '1', '2']

> /Users/someuser/debugger.py(15)main()

-> addition = add(sys.argv[1], sys.argv[2])

(Pdb)

此时我在第18行设置一个断点。
 

1

2

3

4

5

6

7

8

9

10

11

-> addition = add(sys.argv[1], sys.argv[2])

(Pdb) b 18

Breakpoint 1 at /Users/someuser/debugger.py:18

(Pdb) c

We are in add--

3

> /Users/someuser/debugger.py(18)main()

-> print subtraction

(Pdb) p subtraction

-1

(Pdb)

从上面我们可以看到,PDB跳到了第18行并等待下一个指令。

同时,PDB还为该断点分配了一个号码(在本例中是1)。为了以后的执行,我们可以通过开启或禁用断点号码来启用或停用对应的断点。
8. 列表->l

有时在调试的时候,你可能会忘记此时你处在代码的什么地方。在这种情况下,使用“l”将会打印出一个友好的总结,它能够显示出此刻你在代码中的位置。
 

1

2

3

4

5

6

7

8

9

10

11

12

13

['debugger.py', '1', '2']

> /Users/someuser/debugger.py(15)main()

-> addition = add(sys.argv[1], sys.argv[2])

(Pdb) l

 10

 11   def main():

 12     #Assuming our inputs are valid numbers

 13     print sys.argv

 14     pdb.set_trace() # <-- Break point added here

 15 ->   addition = add(sys.argv[1], sys.argv[2])

 16     print addition

 17     subtraction = sub(sys.argv[1], sys.argv[2])

 18     print subtraction

9. 动态分配变量

在调试会话期间,你可以分配变量来帮助你进行调试,知道这些对你来说也是有帮助的。例如:
 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

['debugger.py', '1', '2']

> /Users/someuser/debugger.py(15)main()

-> addition = add(sys.argv[1], sys.argv[2])

(Pdb) n

We are in add--

> /Users/someuser/debugger.py(16)main()

-> print addition

(Pdb) p addition

3 #<--- addition here is 3

(Pdb) addition = 'this is now string' #<--- We changed the value of additon

(Pdb) n

this is now string #<--- Now when we print it we actually gets it as a string. that we just set above.

> /Users/someuser/debugger.py(17)main()

-> subtraction = sub(sys.argv[1], sys.argv[2])

注意:
如果你想设置一些如n(即PDB指令)这样的变量,你应该使用这种指令:
 

1

2

3

(Pdb) !n=5

(Pdb) p n

5

10. 结束->q

最后,在代码的任何地方如果你想结束调试,可以使用“q”,那么正在执行的程序将会终止。

点击拿去
50G+学习视频教程
100+Python初阶、中阶、高阶电子书籍


http://www.ppmy.cn/news/76013.html

相关文章

Qt Quick系列(2)—核心元素类型(1)

&#x1f680;作者&#xff1a;CAccept &#x1f382;专栏&#xff1a;Qt Quick 文章目录 前言ItemRectangleTextImageMouseArea 总结 前言 Qt Quick的元素分为 1、视觉元素&#xff08;如Rectangle&#xff09;具有几何属性 2、非视觉元素&#xff08;如Timer&#xff09;提…

微波基础介绍

1、什么是微波 大家在高中物理中都学过电磁波&#xff0c;可见光、微波都是电磁波波段&#xff0c;如下图所示&#xff0c;可见光谱只占有宽广的电磁波谱的一小部分&#xff1a; 而我们这次的主角微波&#xff0c;是频率范围300MHz到3THz的电磁波&#xff08;1THz1000GHz&…

AI人工智能预处理数据的方法和技术有哪些?

AI人工智能 预处理数据 在人工智能&#xff08;Artificial Intelligence&#xff0c;简称AI&#xff09;领域中&#xff0c;数据预处理是非常重要的一环。它是在将数据输入到模型之前对数据进行处理和清洗的过程。数据预处理可以提高模型的准确性、可靠性和可解释性。 本文将…

python+django植物园性毒源成分管理系统

在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括植物性毒源成分管理系统的网络应用&#xff0c;在外国植物性毒源成分管理系统已经是很普遍的方式&#xff0c;不过国内的植物性毒源成分管理可能还处于起步阶段。植物性毒源成…

YOLO NAS note 1

Git Hub: https://github.com/Deci-AI/super-gradients Yolo-Nas 的代码比YOLO v8 还恐怖。之前的YOLO数据可以通过&#xff1a; coco_detection_yolo_format_train&#xff0c; 和 coco_detection_yolo_format_val 自动转。 这里写目录标题 Train数据获取数据增强训练criteri…

js中的类

1、构造函数与类 class Person{// 构造函数// 构造函数在调用类&#xff0c;实例化对象时调用constructor(name,age){console.log(构造器被调用了&#xff01;);console.log(name,age);// 在构造函数中&#xff0c;this表示当前所创建的对象// this.name对象的属性&#xff0c…

软件设计和架构设计

软件设计和架构设计 1.软件设计 1.1设计 设计是从架构 构件 接口以及系统其他特征定义的过程。 软件设计的结果必须描述系统的架构&#xff0c;系统如何分解和组织构件。 描述构件间的接口。 描述构件必须详细到可进一步构造的程度。 设计是把分析模型转换成设计模型的过…

c++虚函数详解(多态特性)

1.c多态的概念 多态是c的特征之一 多态的分类&#xff1a;静态多态&#xff08;静态联编&#xff09;、动态多态&#xff08;动态联编&#xff09; 静态多态&#xff08;静态联编&#xff09;&#xff1a;函数入口地址 是在 编译阶段 确定&#xff08;运算符重载、函数重载&…

IOS新建应用

一&#xff1a;Application App。普通app。Document App。打开是记事本类似App。Game。新建游戏相关app。RealityKit为新建一个打开摄像机&#xff0c;一个Ar立方体的应用。 SenceKit为有一架飞机旋转的游戏App。 SpirteKit为一个手指头按上会出一个手指特效的应用。 Metal为一…

MySql常用命令总结

1:使用SHOW语句找出在服务器上当前存在什么数据库&#xff1a; mysql> SHOW DATABASES; 2:2、创建一个数据库MYSQLDATA mysql> CREATE DATABASE MYSQLDATA; 3:选择你所创建的数据库 mysql> USE MYSQLDATA; (按回车键出现Database changed 时说明操作成功&#xff01;)…

抖音账号运营技巧,让你的短视频更火爆

抖音是目前最火爆的短视频平台之一&#xff0c;拥有着庞大的用户群体和广阔的市场前景。在这个平台上&#xff0c;每天都有大量的用户在发布自己的短视频内容&#xff0c;让自己的账号脱颖而出并吸引更多的粉丝&#xff0c;成为每个用户所追求的目标。下面就来介绍一些抖音账号…

应用程序和 API 攻击呈上升趋势

Akamai Technologies 发布了一份新的互联网现状报告&#xff0c;标题为“突破安全漏洞&#xff1a;针对组织的应用程序和 API 攻击的兴起”。 报告显示&#xff0c;亚太地区和日本&#xff08;APJ&#xff09;的金融服务业仍然是该地区受攻击最严重的行业&#xff0c;Web 应用…

mqtt服务管理配置

mqtt服务管理配置mosquitto.conf配置文件 windows查找占用端口 netstat -aon|findstr 1883 linux查找占用端口 netstat -antlp|grep “1883” 服务启动 mosquitto -c mosquitto.conf -v 指定端口启动 mosquitto -p 指定端口号码 添加用户 mosquitto_passwd -b “C:/Program Fi…

Docker介绍、常用命令、项目部署

什么是Docker 简单说&#xff1a;Docker就是一个虚拟机&#xff0c;专业说&#xff1a;它是一个开源的容器平台。它和我们常用的VMware有很多相似的地方。 名词解释 镜像/images 由本体打包出来的文件。并不是文件本身&#xff0c;但是具有该文件的功能。举个不太贴切的例子&…

基于Rancherwebhook微服务的弹性伸缩实现

一、引言 随着云计算技术的不断发展&#xff0c;弹性伸缩已成为云环境下实现高可用性、可扩展性、资源优化和负载均衡的重要手段。Rancherwebhook微服务是一种基于容器的云原生应用管理平台&#xff0c;提供了一种方便、快捷、高效的方式来管理容器编排和弹性伸缩。本文将介绍如…

LeetCode:29. 两数相除

29. 两数相除 1&#xff09;题目2&#xff09;思路3&#xff09;代码1.初始代码2.第一次优化3.第二次优化 4&#xff09;结果1.初始结果2.第一次优化结果3.第二次优化结果 1&#xff09;题目 给你两个整数&#xff0c;被除数 dividend 和除数 divisor。将两数相除&#xff0c;…

基于Freertos的ESP-IDF开发——7.WS2812B彩色灯循环

基于Freertos的ESP-IDF开发——7.WS2812B彩色灯循环 0. 前言1. WS2812B简介2. 完整代码3. 演示效果4. 其他FreeRtos文章 0. 前言 本节使用WS2812B实现彩灯循环 开发环境&#xff1a;ESP-IDF 4.3 操作系统&#xff1a;Windows10 专业版 开发板&#xff1a;自制的ESP32-WROOM-3…

Python关于Pandas的iterrows、itertuples等遍历表格时读取不到第一行的问题

一、问题原因 df.iterrows() 是用来遍历 Pandas DataFrame 的方法&#xff0c;它会把 DataFrame 中的每一行转换成一个元组&#xff0c;其中第一个元素是行号&#xff0c;第二个元素是该行的数据。行号从 0 开始。 在使用 df.iterrows() 遍历 DataFrame 的时候发现表格第二行…

CMD与DOS脚本编程【第六章】

预计更新 第一章. 简介和基础命令 1.1 介绍cmd/dos脚本语言的概念和基本语法 1.2 讲解常用的基础命令和参数&#xff0c;如echo、dir、cd等 第二章. 变量和运算符 2.1 讲解变量和常量的定义和使用方法 2.2 介绍不同类型的运算符和运算规则 第三章. 控制流程和条件语句 3.1 介…

组合数学第二讲

可以把取出来的数从小到大排序&#xff0c;第一个数不变&#xff0c;第二个数1&#xff0c;以此类推... 总共的情况为&#xff0c;数字取完后可再依次减回去&#xff0c;保证数在100以内 k-element multisets 引出下面的二项式系数 binomial coefficients&#xff08;二项式系…
最新文章