Python pdb模块的使用
野路子出生,写Python也有段时间了,一般的调试都用的print, PyCharm的debug功能也用的比较少,主要一般也用不到,第二是自己也不怎么会用.
服务器开发,本地根本没有运行的环境,前面学习了unittest,现在一般都会写单元测试,单总有一些情况会发生在意外之中, 更多的时候,我只能使用print大法,输出自己想看的数据或者变量信息,但这确实又慢又臭,很多时候,项目测试运行很慢,好不容易到了测试点,输出的信息可能不够全面,然后又要重新print需要的信息,并再次启动项目,这可真是劳民伤财。
最近单位比较空一点,看了新版的《Effective Python》一书,书中有介绍pdb的使用,以前虽然也知道这个模块,但基于水平有限以及懒等多方面原因,一直没有接触,这次书中的简单介绍以及官网的查看,发现,这个真是一个好东西,服务器调试的神器。
如果还是很懒不想看pdb,上次跟一个群友交流,他说一般用print(locals()),在需要的地方输出,一试还真是一个好东西,一直知道locals函数,看来用在测试的地方真不错
参考:《Effective Python》书P322页
官网链接:https://docs.python.org/zh-cn/3/library/pdb.html
import math def compute_rmse(observed, ideal):
total_err_2 = 0
count = 0
for got, wanted in zip(observed, ideal):
err_2 = (got - wanted) ** 2
breakpoint() # Start the debugger here
# 与上面的breakpoint效果一致
# import pdb
# pdb.set_trace()
total_err_2 += err_2
count += 1 mean_err = total_err_2 / count
rmse = math.sqrt(mean_err)
return rmse result = compute_rmse(
[1.8, 1.7, 3.2, 6],
[2, 1.5, 3, 5])
print(result)
Python3.7 新版功能: 内置函数 breakpoint()
,当以默认参数调用它时,可以用来代替 import pdb; pdb.set_trace()
。
上面的文字已经说明了示例代码中的情况, 通过在需要断点的地方进行breakpoint()的插入,就会在该处断点,并弹出pdb的交易界面。
很多时候,我们并不知道具体那里会出问题,或者出问题的地方比较随机,手动设置breakpoint不合适.
例如:
python3 -m pdb myscript.py
当作为脚本调用时,如果要调试的程序异常退出,pdb 调试将自动进入事后调试。事后调试之后(或程序正常退出之后),pdb 将重新启动程序。自动重启会保留 pdb 的状态(如断点),在大多数情况下,这比在退出程序的同时退出调试器更加实用。
书中的介绍还有一种方式为
python3 -m pdb -c continue myscript.py的方式运行
其实都一样,第二种就是第一种运行之后,直接接入continue命令的情况.
上面摘录的那段话,我的实际使用为感觉情况为:
当 python3 -m pdb myscript.py的执行,马上进行调试界面,
敲入continue命令后,会去寻找运行的项目中的breakpoint或者遇到错误时的,自动生成一个断点,就好比在那个错误之前手动设置了一个breakponit, 你可以在那个pdb环境中调试自己需要的参数,当q退出的时候,它将返回并返回最初的pdb状态。
还有一种在交互的情况下,进入调试模块,我想一般情况下,我应该不会用,所以就不写了.
下面是摘抄至官网的相关命令的含义
h(elp)
[command]
-
不带参数时,显示可用的命令列表。参数为 command 时,打印有关该命令的帮助。
help pdb
显示完整文档(即pdb
模块的文档字符串)。由于 command 参数必须是标识符,因此要获取!
的帮助必须输入help exec
。
w(here)
-
打印堆栈回溯,最新一帧在底部。有一个箭头指向当前帧,该帧决定了大多数命令的上下文。
d(own)
[count]
-
在堆栈回溯中,将当前帧向下移动 count 级(默认为 1 级,移向更新的帧)。
u(p)
[count]
-
在堆栈回溯中,将当前帧向上移动 count 级(默认为 1 级,移向更老的帧)。
b(reak)
[([filename:]lineno | function) [, condition]]
-
如果带有 lineno 参数,则在当前文件相应行处设置一个断点。如果带有 function 参数,则在该函数的第一条可执行语句处设置一个断点。行号可以加上文件名和冒号作为前缀,以在另一个文件(可能是尚未加载的文件)中设置一个断点。另一个文件将在
sys.path
范围内搜索。请注意,每个断点都分配有一个编号,其他所有断点命令都引用该编号。如果第二个参数存在,它应该是一个表达式,且它的计算值为 true 时断点才起作用。
如果不带参数执行,将列出所有中断,包括每个断点、命中该断点的次数、当前的忽略次数以及关联的条件(如果有)。
tbreak
[([filename:]lineno | function) [, condition]]
-
临时断点,在第一次命中时会自动删除。它的参数与
break
相同。
cl(ear)
[filename:lineno | bpnumber ...]
-
如果参数是 filename:lineno,则清除此行上的所有断点。如果参数是空格分隔的断点编号列表,则清除这些断点。如果不带参数,则清除所有断点(但会先提示确认)。
disable
[bpnumber ...]
-
禁用断点,断点以空格分隔的断点编号列表给出。禁用断点表示它不会导致程序停止执行,但是与清除断点不同,禁用的断点将保留在断点列表中并且可以(重新)启用。
enable
[bpnumber ...]
-
启用指定的断点。
ignore
bpnumber [count]
-
为指定的断点编号设置忽略次数。如果省略 count,则忽略次数将设置为 0。忽略次数为 0 时断点将变为活动状态。如果为非零值,在每次达到断点,且断点未禁用,且关联条件计算值为 true 的情况下,该忽略次数会递减。
condition
bpnumber [condition]
-
为断点设置一个新 condition,它是一个表达式,且它的计算值为 true 时断点才起作用。如果没有给出 condition,则删除现有条件,也就是将断点设为无条件。
commands
[bpnumber]
-
为编号是 bpnumber 的断点指定一系列命令。命令内容将显示在后续的几行中。输入仅包含
end
的行来结束命令列表。举个例子:(Pdb) commands 1
(com) p some_variable
(com) end
(Pdb)要删除断点上的所有命令,请输入
commands
并立即以end
结尾,也就是不指定任何命令。如果不带 bpnumber 参数,
commands
作用于最后一个被设置的断点。可以为断点指定命令来重新启动程序。只需使用
continue
或step
命令或其他可以继续运行程序的命令。如果指定了某个继续运行程序的命令(目前包括
continue
,step
,next
,return
,jump
,quit
及它们的缩写)将终止命令列表(就像该命令后紧跟着 end)。因为在任何时候继续运行下去(即使是简单的 next 或 step),都可能会遇到另一个断点,该断点可能具有自己的命令列表,这导致要执行的列表含糊不清。如果在命令列表中加入 'silent' 命令,那么在该断点处停下时就不会打印常规信息。如果希望断点打印特定信息后继续运行,这可能是理想的。如果没有其他命令来打印一些信息,则看不到已达到断点的迹象。
s(tep)
-
运行当前行,在第一个可以停止的位置(在被调用的函数内部或在当前函数的下一行)停下。
n(ext)
-
继续运行,直到运行到当前函数的下一行,或当前函数返回为止。(
next
和step
之间的区别在于,step
进入被调用函数内部并停止,而next
(几乎)全速运行被调用函数,仅在当前函数的下一行停止。)
unt(il)
[lineno]
-
如果不带参数,则继续运行,直到行号比当前行大时停止。
如果带有行号,则继续运行,直到行号大于或等于该行号时停止。在这两种情况下,当前帧返回时也将停止。
在 3.2 版更改: 允许明确给定行号。
r(eturn)
-
继续运行,直到当前函数返回。
c(ont(inue))
-
继续运行,仅在遇到断点时停止。
j(ump)
lineno
-
设置即将运行的下一行。仅可用于堆栈最底部的帧。它可以往回跳来再次运行代码,也可以往前跳来跳过不想运行的代码。
l(ist)
[first[, last]]
-
列出当前文件的源代码。如果不带参数,则列出当前行周围的 11 行,或继续前一个列表。如果用
.
作为参数,则列出当前行周围的 11 行。如果带有一个参数,则列出那一行周围的 11 行。如果带有两个参数,则列出所给的范围中的代码;如果第二个参数小于第一个参数,则将其解释为列出行数的计数。当前帧中的当前行用
->
标记。如果正在调试异常,且最早抛出或传递该异常的行不是当前行,则那一行用>>
标记。3.2 新版功能:
>>
标记。
ll
| longlist
-
列出当前函数或帧的所有源代码。相关行的标记与
list
相同。3.2 新版功能.
a(rgs)
-
打印当前函数的参数列表。
p
expression
-
在当前上下文中运行 expression 并打印它的值。
注解
print()
也可以使用,但它不是一个调试器命令 --- 它执行 Pythonprint()
函数。
whatis
expression
-
打印 expression 的类型。
source
expression
-
尝试获取给定对象的源代码并显示出来。
3.2 新版功能.
display
[expression]
-
如果表达式的值发生改变则显示它的值,每次将停止执行当前帧。
不带表达式则列出当前帧的所有显示表达式。
3.2 新版功能.
undisplay
[expression]
-
不再显示当前帧中的表达式。 不带表达式则清除当前帧的所有显示表达式。
3.2 新版功能.
interact
-
启动一个交互式解释器(使用
code
模块),它的全局命名空间将包含当前作用域中的所有(全局和局部)名称。3.2 新版功能.
alias
[name [command]]
-
创建一个标识为 name 的别名来执行 command。 执行的命令 不可 加上引号。 可替换形参可通过
%1
,%2
等来标示,而%*
会被所有形参所替换。 如果没有给出命令,则会显示 name 的当前别名。 如果没有给出参数,则会列出所有别名。别名允许嵌套并可包含能在 pdb 提示符下合法输入的任何内容。 请注意内部 pdb 命令 可以 被别名所覆盖。 这样的命令将被隐藏直到别名被移除。 别名会递归地应用到命令行的第一个单词;行内的其他单词不会受影响。
作为示例,这里列出了两个有用的别名(特别适合放在
.pdbrc
文件中):# Print instance variables (usage "pi classInst")
alias pi for k in %1.__dict__.keys(): print("%1.",k,"=",%1.__dict__[k])
# Print instance variables in self
alias ps pi self
unalias
name
-
删除指定的别名。
!
statement
-
在当前堆栈帧的上下文中执行 (单行) statement。 感叹号可以被省略,除非语句的第一个单词与调试器命令重名。 要设置全局变量,你可以在同一行上为赋值命令添加前缀的
global
语句,例如:(Pdb) global list_options; list_options = ['-l']
(Pdb)
run
[args ...]
restart
[args ...]
-
重启被调试的 Python 程序。 如果提供了参数,它会用
shlex
来拆分且拆分结果将被用作新的sys.argv
。 历史、中断点、动作和调试器选项将被保留。restart
是run
的一个别名。
q(uit)
-
退出调试器。 被执行的程序将被中止。
debug
code
-
进入一个对代码参数执行步进的递归调试器(该参数是在当前环境中执行的任意表达式或语句)。
retval
-
打印函数最后一次返回的返回值。
感觉官网的翻译,比书中的详细,以后在简历中必须写上会pdb调试,以及单元测试完善,要不然我自己作为过来人,感觉你肯定不是一个合格的Python开发
或者你写的项目是在太小了,一个模块就到底。
Python pdb模块的使用的更多相关文章
- [Python]-pdb模块-单步调试
使用pdb模块辅助python调试. import pdb 断点模式 在需要调试的语句前设置断点,加入这行代码: pdb.set_trace() 程序运行到这就会进入断点调试模式. 输入 作用 n 运 ...
- python pdb模块
参考文件http://pythonconquerstheuniverse.wordpress.com/category/Python-debugger/ 翻译不是一一对应 Debug功能对于devel ...
- 使用pdb模块调试Python
在Python中,我们需要debug时,有三种方式: 加log语句.最简单的方式是添加print()语句来输出我们想要获知的状态或者变量,好处是简单容易操作,坏处是debug完了之后,还需要将prin ...
- python 各模块
01 关于本书 02 代码约定 03 关于例子 04 如何联系我们 1 核心模块 11 介绍 111 内建函数和异常 112 操作系统接口模块 113 类型支持模块 114 正则表达式 115 语言支 ...
- Python 日志模块实例
python 打印对象的所有属性值: def prn_obj(obj): print '\n'.join(['%s:%s' % item for item in obj.__dict__.it ...
- Python logging模块无法正常输出日志
废话少说,先上代码 File:logger.conf [formatters] keys=default [formatter_default] format=%(asctime)s - %(name ...
- Python标准模块--threading
1 模块简介 threading模块在Python1.5.2中首次引入,是低级thread模块的一个增强版.threading模块让线程使用起来更加容易,允许程序同一时间运行多个操作. 不过请注意,P ...
- Python的模块引用和查找路径
模块间相互独立相互引用是任何一种编程语言的基础能力.对于“模块”这个词在各种编程语言中或许是不同的,但我们可以简单认为一个程序文件是一个模块,文件里包含了类或者方法的定义.对于编译型的语言,比如C#中 ...
- Python Logging模块的简单使用
前言 日志是非常重要的,最近有接触到这个,所以系统的看一下Python这个模块的用法.本文即为Logging模块的用法简介,主要参考文章为Python官方文档,链接见参考列表. 另外,Python的H ...
- Python标准模块--logging
1 logging模块简介 logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级.日志保存路径.日志文件回滚等:相比print,具备如下优点: 可以通过设置不同 ...
随机推荐
- 阻塞I/O,非阻塞I/O,同步I/O,异步I/O
根据应用程序是否阻塞自身运行分为: 阻塞I/O:是指应用程序在执行I/O操作后,如果没有获得响应, 就会阻塞当前线程,不能执行其他任务. 非阻塞I/O:是指应用程序在执行I/O操作后 ...
- 查看linux 用户
sudo cat /etc/passwd|grep -v nologin|grep -v halt|grep -v shutdown|awk -F":" '{ print $1}' ...
- svn 中如何checkout出单个文件
A 通过命令行操作 1.检出目录images svn co --depth=empty http://www.iusesvn.com/project1/images images_work_dir 这 ...
- 全国IP段列表
http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest Linux下执行如下命令可将中国大陆ip格式化并导出 wget -c htt ...
- C# RGB转Brush
C#中自定义一个Brush,使用Color赋RGB值给Brush: dataGrid2.HorizontalGridLinesBrush = new SolidColorBrush(System.Wi ...
- 从零搭建hadoop集群之安装虚拟机
1. 打开 VMware 2. 点击编辑 -> 虚拟网络编辑器 点击VMnet8 选中NAT模式(于虚拟机共享主机的ip地址) 设置子网IP 点击NAT设置 3. 设置网关 :和子网IP ...
- win10安装MAT并单独配置jdk11
1.下载MAT 2.下载jdk11 3.配置jdk11 MAT解压后,在MemoryAnalyzer.ini配置文件开头添加配置指向jdk11,如下: -vm C:\Program Files\Jav ...
- OpenCv:边缘处理&Canny边缘检测
卷积边缘: 一.在进行卷积的时候,对于原图像(1,1)的位置,左.上方没有足够的像素做卷积. 二.通常,在卷积之前,在原图增加边缘像素,比如(3*3的,增加一个像素) 三.增加像素值得处理方法,通常有 ...
- linux 查询目录文件大小
- debian/ubuntu下安装nodejs npm
举例:在 /home 目录下 wget https://nodejs.org/dist/v16.17.1/node-v16.17.1-linux-x64.tar.xz nodejs官网下载地址,目前最 ...