用python语言调试程序你用的平台是_Python 程序如何高效地调试?

看LZ的意思是想了解出现BUG怎么调试的问题。BUG有2种:

第一种,直接造成了错误,程序抛了个异常。楼上已经讲了IPython,是的。首先我先写一个有问题的例子:

a = 1

b = 0

a / b

执行肯定是报错的:

❯ python test.py

Traceback (most recent call last):

File "test.py", line 4, in

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 ()

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)()

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 ):

========================================

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页面渲染成一个可调试和可执行的环境,直接到上面调试:

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之美」):

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值