Python 如何调试程序崩溃错误
作者:David Beazley 发布时间:2022-04-27 15:22:30
问题
你的程序崩溃后该怎样去调试它?
解决方案
如果你的程序因为某个异常而崩溃,运行 python3 -i someprogram.py
可执行简单的调试。 -i 选项可让程序结束后打开一个交互式shell。 然后你就能查看环境,例如,假设你有下面的代码:
# sample.py
def func(n):
return n + 10
func('Hello')
运行 python3 -i sample.py
会有类似如下的输出:
bash % python3 -i sample.py
Traceback (most recent call last):
File "sample.py", line 6, in <module>
func('Hello')
File "sample.py", line 4, in func
return n + 10
TypeError: Can't convert 'int' object to str implicitly
>>> func(10)
20
>>>
如果你看不到上面这样的,可以在程序崩溃后打开Python的调试器。例如:
>>> import pdb
>>> pdb.pm()
> sample.py(4)func()
-> return n + 10
(Pdb) w
sample.py(6)<module>()
-> func('Hello')
> sample.py(4)func()
-> return n + 10
(Pdb) print n
'Hello'
(Pdb) q
>>>
如果你的代码所在的环境很难获取交互shell(比如在某个服务器上面), 通常可以捕获异常后自己打印跟踪信息。例如:
import traceback
import sys
try:
func(arg)
except:
print('**** AN ERROR OCCURRED ****')
traceback.print_exc(file=sys.stderr)
要是你的程序没有崩溃,而只是产生了一些你看不懂的结果, 你在感兴趣的地方插入一下 print()
语句也是个不错的选择。 不过,要是你打算这样做,有一些小技巧可以帮助你。 首先,traceback.print_stack()
函数会你程序运行到那个点的时候创建一个跟踪栈。例如:
>>> def sample(n):
... if n > 0:
... sample(n-1)
... else:
... traceback.print_stack(file=sys.stderr)
...
>>> sample(5)
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in sample
File "<stdin>", line 3, in sample
File "<stdin>", line 3, in sample
File "<stdin>", line 3, in sample
File "<stdin>", line 3, in sample
File "<stdin>", line 5, in sample
>>>
另外,你还可以像下面这样使用 pdb.set_trace()
在任何地方手动的启动调试器:
import pdb
def func(arg):
...
pdb.set_trace()
...
当程序比较大而你想调试控制流程以及函数参数的时候这个就比较有用了。 例如,一旦调试器开始运行,你就能够使用 print 来观测变量值或敲击某个命令比如 w 来获取追踪信息。
讨论
不要将调试弄的过于复杂化。一些简单的错误只需要观察程序堆栈信息就能知道了, 实际的错误一般是堆栈的最后一行。 你在开发的时候,也可以在你需要调试的地方插入一下 print()
函数来诊断信息(只需要最后发布的时候删除这些打印语句即可)。
调试器的一个常见用法是观测某个已经崩溃的函数中的变量。 知道怎样在函数崩溃后进入调试器是一个很有用的技能。
当你想解剖一个非常复杂的程序,底层的控制逻辑你不是很清楚的时候, 插入 pdb.set_trace()
这样的语句就很有用了。
实际上,程序会一直运行到碰到 set_trace()
语句位置,然后立马进入调试器。 然后你就可以做更多的事了。
如果你使用IDE来做Python开发,通常IDE都会提供自己的调试器来替代pdb。 更多这方面的信息可以参考你使用的IDE手册。
来源:https://python3-cookbook.readthedocs.io/zh_CN/latest/c14/p12_debugging_basic_program_crashes.html


猜你喜欢
- 我想大家在用Sql2005一般都是.NET2005自带的SQL Server 2005是SQL Server2005 Express版本的,
- Python中if __name__ == ‘__main__‘作用要搞清楚这个问题,要知道以py作
- 一、绘制折线图使用plot()绘制折线图常用的参数:x:表示x轴的数据y:表示y轴的数据fmt:表示快速设置条样式的格式字符串。label:
- 效果演示基础源码1.基础设置(tools部分)这个部分设置马里奥以及游戏中蘑菇等怪的的移动设置。import osimport pygame
- 快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-Conq
- 本文实例讲述了Python文件及目录操作的方法。分享给大家供大家参考。具体分析如下:在python中对文件及目录的操作一般涉及多os模块,o
- 可是,其体积仍然很庞大。所以,在日常工作中,如何给SQL Server的备份文件瘦身,就是很多数据库管理员所关心的问题了。 也许微软的数据库
- cv2库在opencv库内,因此需要下载opencv-python1、打开windows命令行:win+Rcmd2、更新pip版本(不一定要
- 关于tensor.repeat()的使用考虑到很多人在学习这个函数,我想在这里提 一个建议:强烈推荐 使用 einops 模块中的 repe
- python装饰器就是用于扩展原函数功能的一种函数,这个函数特殊的地方就是它的返回值也是一个函数,使用Python装饰器的一个好处就是:在不
- 前言近日在做一个报表功能里面有一个这样的需求是统计各部门在某一月入职和离职的人数我的步骤先查出入职的人数SELECT dept ,COUNT
- 摘要:大家提到Mysql的性能优化都是注重于优化sql以及索引来提升查询性能,大多数产品或者网站面临的更多的高并发数据读取问题。然而在大量写
- pytorch里面的maxpool,有一个属性叫ceil_mode,这个属性在api里面的解释是ceil_mode: when True,
- 参数说明以官方说明为例,gather()函数需要三个参数,输入input,维度dim,以及索引indexinput必须为Tensor类型di
- 如何在约定时间显示特定的提示信息?<%Function Greeting()
- 一、效果展示1、普通查询加序号SELECT t1.NAME,( @i := @i + 1 ) AS '序号' FROM t1
- 使用gorm.Model后无法查询数据Scan error on column index 1, name “created_at”提示:S
- mysql 误删除ibdata1之后如何恢复如果误删除了在线服务器中mysql innodb相关的数据文件ibdata1以及日志文件 ib_
- 本文实例讲述了Django框架模型简单介绍与使用。分享给大家供大家参考,具体如下:ORM介绍ORM Object relational ma
- 起因 前几天去国图拍了一本书,一本心理学方面的书,也许你问我为什么不去买一本,或者去网上找pdf。 其实吧,关于心理学方面的书可以说在市面上