Python 程序如何高效地调试?
链接:https://www.zhihu.com/question/21572891/answer/26046582
来源:知乎
著作权归作者所有,转载请联系作者获得授权。
应该用过 IPython 吧?想象一下,抛出异常时自动把你带到 IPython Shell 是不是很开心?而且和普通的IPython不同,这个时候可以调用 p (print), up(up stack), down(down stack) 之类的命令。还能创建临时变量,执行任意函数。
事实上这是可以实现的, 而且很简单,不过你要先安装 IPython。然后把以下代码保存为 `crash_on_ipy.py`
import sys
class ExceptionHook:
instance = None
def __call__(self, *args, **kwargs):
if self.instance is None:
from IPython.core import ultratb
self.instance = ultratb.FormattedTB(mode='Plain',
color_scheme='Linux', call_pdb=1)
return self.instance(*args, **kwargs)
sys.excepthook = ExceptionHook()
然后在你的项目代码某个地方 import crash_on_ipy 就可以了。<img data-rawheight="297" data-rawwidth="374" src="https://pic2.zhimg.com/13e5ce52cf8dec0a1b1dc4480ed6b27d_b.jpg" class="content_image" width="374">
这个方法不需要 IDE.
import pdb
pdb.set_trace()
将上面2行加入到需要加断点的代码处,运行时,执行在此处即可中断,单步、继续、查看变量值等功能都有,不妨help下。
链接:https://www.zhihu.com/question/21572891/answer/123220574
来源:知乎
著作权归作者所有,转载请联系作者获得授权。
第一种,直接造成了错误,程序抛了个异常。楼上已经讲了IPython,是的。首先我先写一个有问题的例子:
a = 1
b = 0
a / b
执行肯定是报错的:
❯ python test.py
Traceback (most recent call last):
File "test.py", line 4, in <module>
a / b
ZeroDivisionError: integer division or modulo by zero
有点经验的人一眼看去就知道 是因为分母是0造成的。可是脚本执行结束了,要是调试还得不断的在对应位置加print。绝招就是:
❯ ipython test.py --pdb
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
/Users/dongweiming/test/test.py in <module>()
2 b = 0
3
----> 4 a / b
ZeroDivisionError: integer division or modulo by zero
*** NameError: name 'pdb' is not defined
> /Users/dongweiming/test/test.py(4)<module>()
1 a = 1
2 b = 0
3
----> 4 a / b
ipdb> p b # p是print的别名
0
ipdb> p a
1
ipdb>
程序运行在错误的地方,嘎.. 停住了,保存了错误上下文,进入pdb环境,直接调试去吧,不要太开心。
说到这里,ipdb(pdb)可以设置断点、单步调试、进入函数调试、查看当前代码、查看栈片段、动态改变变量的值等。它有很多快捷键:
ipdb> help
Documented commands (type help <topic>):
========================================
EOF bt cont enable jump pdef psource run unt
a c continue exit l pdoc q s until
alias cl d h list pfile quit step up
args clear debug help n pinfo r tbreak w
b commands disable ignore next pinfo2 restart u whatis
break condition down j p pp return unalias where
其中up,down,n,j,l,where,s, args等我都非常常用,我非常建议你每个快捷键都了解一下。当然很懒的话,你们也有福利,看 Python 代码调试技巧 。
第二种:隐藏BUG,也就是并没有报错,但是输出不符合预期,这种的比较烦,因为如果你经验少写的时候又不咋专心的话,基本上就得挨个地方去确认,有人说,「import pdb pdb.set_trace() 」,嗯很标准的方案,但是我一般不用。原因是什么呢,比如调试Web应用,如果set_trace()的话,需要点多个next才能到你想调试的地方,手指头都点木了。。所以我一般使用如下三个方法:
1. 抛异常。直接让你想要调试的位置让它先跑个异常,比如Flask的DEBUG的模式下,werkzeug里面的DebuggedApplication就会把Web页面渲染成一个可调试和可执行的环境,直接到上面调试:
&lt;img src="https://pic4.zhimg.com/944e68e6bdac1ed89bc220a59b8f68d7_b.png" data-rawwidth="660" data-rawheight="613" class="origin_image zh-lightbox-thumb" width="660" data-original="https://pic4.zhimg.com/944e68e6bdac1ed89bc220a59b8f68d7_r.png"&gt;2. 2. 在对应位置使用print和logging。这是最基础的玩法。我一般只会在已经心理有数,只是需要看看日志输出来确认的时候加临时的。平时的应用日志也会有常规的记录,并且会记录堆栈(当然,使用sentry之类的方式搜集日志是最好的),比如重要的上线过程中,出了问题但是开发环境又不好模拟出来的时候,「tail -f」日志文件们,这样出现问题一看就看到了。 说到这里再推荐一个很有意思的项目: GitHub - zestyping/q: Quick and dirty debugging output for tired programmers. ,它是在我看pycon2013演讲中发现的,有兴趣可以看看, PyVideo.org · Lightning Talks。我之前常用它。
3. 自己维护一些用于调试的库。我会把工作中常用到的、有用的一些函数、方法搜集起来,放在一个库里。其中有个获取调用栈的函数类似这样:
import sys
def get_cur_info():
print sys._getframe().f_code.co_filename # 当前文件名
print sys._getframe(0).f_code.co_name # 当前函数名
print sys._getframe(1).f_code.co_name # 调用该函数的函数的名字,如果没有被调用,则返回module
print sys._getframe().f_lineno # 当前行号
可以通过看当前上下文的调用栈的输出来帮助你揪出那个隐藏的「虫」
Python 程序如何高效地调试?的更多相关文章
- Python程序高效地调试
现在我在debug python程序就只是简单在有可能错误的地方print出来看一下,不知道python有没像c++的一些IDE一样有单步调试这类的工具?或者说各位python大神一般是怎么debug ...
- PDB调试Python程序
pdb是python内置的调试工具, 它可以在终端中调试Python程序, 这允许pdb在很多无法安装IDE的服务器上使用. 虽然远程调试使用广泛, 但在必要的时候(比如难以在本地搭建运行环境)pdb ...
- 用PDB库调试Python程序
Python自带的pdb库,发现用pdb来调试程序还是很方便的,当然了,什么远程调试,多线程之类,pdb是搞不定的. 用pdb调试有多种方式可选: 1. 命令行启动目标程序,加上-m参数,这样调用my ...
- python程序的调试方法
[转自:http://blog.csdn.net/luckeryin/article/details/4477233] 本文讨论在没有方便的IDE工具可用的情况下,使用pdb调试python程序 ...
- [转] python程序的调试方法
qi09 原文 python程序的调试方法 本文讨论在没有方便的IDE工具可用的情况下,使用pdb调试python程序 源码例子 例如,有模拟税收计算的程序: #!/usr/bin/python de ...
- [转] 用PDB库调试Python程序
Python自带的pdb库,发现用pdb来调试程序还是很方便的,当然了,什么远程调试,多线程之类,pdb是搞不定的. 用pdb调试有多种方式可选: 1. 命令行启动目标程序,加上-m参数,这样调用my ...
- 调试python 程序的几种方法总结
程序能一次写完并正常运行的概率很小,基本不超过1%.总会有各种各样的bug需要修正.有的bug很简单,看看错误信息就知道,有的bug很复杂,我们需要知道出错时,哪些变量的值是正确的,哪些变量的值是错误 ...
- 利用Pycharm断点调试Python程序
利用Pycharm断点调试Python程序 1.代码 准备没有语法错误的Python程序: #!/usr/bin/pythonimport numpy as np class Network: def ...
- Python入门(一):PTVS写Python程序,调试模式下input()提示文字乱码问题
前两天写了Python入门(一),里面提到,使用VS2013+PTVS进行Python开发. 就在准备为第二篇写个demo的时候,发现了一个问题,各种解决无果,有些纠结 Python中输入函数是inp ...
随机推荐
- atitit.提升开发效率---MDA 软件开发方式的革命(3)----自动化建表
atitit.提升开发效率---MDA 软件开发方式的革命(3)----自动化建表 1. 建模在后自动建表 1 1. 传统上,需要首先建表,在业务编码.. 1 2. 模型驱动建表---更多简化法是在建 ...
- 将外卖O2O广告一棍子打成竞价排名,秤把平了吗?
近日,诸多媒体报道称美团外卖.饿了么等外卖O2O将竞价排名引入外卖平台当中进行广告运营一事闹得沸沸扬扬.那么,美团外卖.饿了么真的都是竞价排名吗? 其实,美团外卖的付费推广仅仅只是针对列表的固定位置, ...
- JavaWeb学习总结(十七)——JSP中的九个内置对象
一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet ...
- 在主方法中定义一个大小为50的一维整型数组,数组i名为x,数组中存放着{1,3,5,…,99}输出这个数组中的所有元素,每输出十个换一行
package hanqi; import java.util.Scanner; public class Test7 { public static void main(String[] args) ...
- 大家一起写mvc(一)
关于java的mvc框架层出不穷,可能大家都会用,但是具体的原理知道不知道呢.所以我想写一个写一个简单mvc的系列博客,主要面向想了解这些原理的. 其实所谓的mvc框架,基本都是一个原理,就是配置一个 ...
- shell日期的应用
#!bin/bash del_table() { #月初的第一天 month_first_day=`date +%Y%m01` #要删除的日期 last_7day_ago=`date -d " ...
- Unity3D编程学习分享
学习地址:http://www.ixueyun.com/lessons/detail-lessonId-692.html 一.课程概述: 以前大部分3D游戏出现在pc和ps.XBox等专业游戏主机上, ...
- Beego源码分析(转)
摘要 beego 是 @astaxie 开发的重量级Go语言Web框架.它有标准的MVC模式,完善的功能模块,和优异的调试和开发模式等特点.并且beego在国内企业用户较多,社区发达和Q群,文档齐全, ...
- 在Windows下使用Nodist进行Node版本控制
完全卸载Node.js 首先卸载Node.js应用程序 确认在C:\Program Files中没有Nodejs目录 确认在C:\Program Files (x86)没有Nodejs目录 删除C:\ ...
- ASP.NET Web API中的参数绑定总结
ASP.NET Web API中的action参数类型可以分为简单类型和复杂类型. HttpResponseMessage Put(int id, Product item) id是int类型,是简单 ...