实时搜索: python怎么调试

python怎么调试

741条评论 6058人喜欢 2391次阅读 554人点赞
vscode Python环境调试输出很多没用的东西,怎么把这些东西去掉,如图除了Hello其余都是没用的,怎么让调试的时候不输出没用的东西?求解答,另外我不是新手,刷经验的请滚开,谢谢! ...

怎样调试 日志 python 代码: 使用 pdb 进行调试
pdb 是 python 自带的一个包,为 python 程序提供了一种交互的源代码调试功能,主要特性包括设置断点、单步调试、进入函数调试、查看当前代码、查看栈片段、动态改变变量的值等。pdb 提供了一些常用的调试命令,详情见表 1。
表 1. pdb 常用命令

命令
解释

break 或 b 设置断点
设置断点

continue 或 c
继续执行程序

list 或 l
查看当前行的代码段

step 或 s
进入函数

return 或 r
执行代码直到从当前函数返回

exit 或 q
中止并退出

next 或 n
执行下一行

pp
打印变量的值

help
帮助

下面结合具体的实例讲述如何使用 pdb 进行调试。
清单 1. 测试代码示例
import pdb
a = "aaa"
pdb.set_trace()
b = "bbb"
c = "ccc"
final = a + b + c
print final

开始调试:直接运行脚本,会停留在 pdb.set_trace() 处,选择 n+enter 可以执行当前的 statement。在第一次按下了 n+enter 之后可以直接按 enter 表示重复执行上一条 debug 命令。
清单 2. 利用 pdb 调试
[root@rcc-pok-idg-2255 ~]# python epdb1.py
> /root/epdb1.py(4)?()
-> b = "bbb"
(Pdb) n
> /root/epdb1.py(5)?()
-> c = "ccc"
(Pdb)
> /root/epdb1.py(6)?()
-> final = a + b + c
(Pdb) list
1 import pdb
2 a = "aaa"
3 pdb.set_trace()
4 b = "bbb"
5 c = "ccc"
6 -> final = a + b + c
7 print final
[EOF]
(Pdb)
[EOF]
(Pdb) n
> /root/epdb1.py(7)?()
-> print final
(Pdb)

退出 debug:使用 quit 或者 q 可以退出当前的 debug,但是 quit 会以一种非常粗鲁的方式退出程序,其结果是直接 crash。
清单 3. 退出 debug
[root@rcc-pok-idg-2255 ~]# python epdb1.py
> /root/epdb1.py(4)?()
-> b = "bbb"
(Pdb) n
> /root/epdb1.py(5)?()
-> c = "ccc"
(Pdb) q
Traceback (most recent call last):
File "epdb1.py", line 5, in ?
c = "ccc"
File "epdb1.py", line 5, in ?
c = "ccc"
File "/usr/lib64/python2.4/bdb.py", line 48, in trace_dispatch
return self.dispatch_line(frame)
File "/usr/lib64/python2.4/bdb.py", line 67, in dispatch_line
if self.quitting: raise BdbQuit
bdb.BdbQuit

打印变量的值:如果需要在调试过程中打印变量的值,可以直接使用 p
加上变量名,但是需要注意的是打印仅仅在当前的 statement 已经被执行了之后才能看到具体的值,否则会报 NameError: <
exceptions.NameError … ....> 错误。
清单 4. debug 过程中打印变量
[root@rcc-pok-idg-2255 ~]# python epdb1.py
> /root/epdb1.py(4)?()
-> b = "bbb"
(Pdb) n
> /root/epdb1.py(5)?()
-> c = "ccc"
(Pdb) p b
'bbb'
(Pdb)
'bbb'
(Pdb) n
> /root/epdb1.py(6)?()
-> final = a + b + c
(Pdb) p c
'ccc'
(Pdb) p final
*** NameError: <exceptions.NameError instance at 0x1551b710 >
(Pdb) n
> /root/epdb1.py(7)?()
-> print final
(Pdb) p final
'aaabbbccc'
(Pdb)

使用 c 可以停止当前的 debug 使程序继续执行。如果在下面的程序中继续有 set_statement() 的申明,则又会重新进入到 debug 的状态,读者可以在代码 print final 之前再加上 set_trace() 验证。
清单 5. 停止 debug 继续执行程序
[root@rcc-pok-idg-2255 ~]# python epdb1.py
> /root/epdb1.py(4)?()
-> b = "bbb"
(Pdb) n
> /root/epdb1.py(5)?()
-> c = "ccc"
(Pdb) c
aaabbbccc

显示代码:在 debug 的时候不一定能记住当前的代码块,如要要查看具体的代码块,则可以通过使用 list 或者 l 命令显示。list 会用箭头 -> 指向当前 debug 的语句。
清单 6. debug 过程中显示代码
[root@rcc-pok-idg-2255 ~]# python epdb1.py
> /root/epdb1.py(4)?()
-> b = "bbb"
(Pdb) list
1 import pdb
2 a = "aaa"
3 pdb.set_trace()
4 -> b = "bbb"
5 c = "ccc"
6 final = a + b + c
7 pdb.set_trace()
8 print final
[EOF]
(Pdb) c
> /root/epdb1.py(8)?()
-> print final
(Pdb) list
3 pdb.set_trace()
4 b = "bbb"
5 c = "ccc"
6 final = a + b + c
7 pdb.set_trace()
8 -> print final
[EOF]
(Pdb)

在使用函数的情况下进行 debug
清单 7. 使用函数的例子
import pdb
def combine(s1,s2): # define subroutine combine, which...
s3 = s1 + s2 + s1 # sandwiches s2 between copies of s1, ...
s3 = '"' + s3 +'"' # encloses it in double quotes,...
return s3 # and returns it.
a = "aaa"
pdb.set_trace()
b = "bbb"
c = "ccc"
final = combine(a,b)
print final

如果直接使用 n 进行 debug 则到 final=combine(a,b)
这句的时候会将其当做普通的赋值语句处理,进入到 print final。如果想要对函数进行 debug 如何处理呢 ? 可以直接使用 s
进入函数块。函数里面的单步调试与上面的介绍类似。如果不想在函数里单步调试可以在断点处直接按 r 退出到调用的地方。
清单 8. 对函数进行 debug
[root@rcc-pok-idg-2255 ~]# python epdb2.py
> /root/epdb2.py(10)?()
-> b = "bbb"
(Pdb) n
> /root/epdb2.py(11)?()
-> c = "ccc"
(Pdb) n
> /root/epdb2.py(12)?()
-> final = combine(a,b)
(Pdb) s
--Call--
> /root/epdb2.py(3)combine()
-> def combine(s1,s2): # define subroutine combine, which...
(Pdb) n
> /root/epdb2.py(4)combine()
-> s3 = s1 + s2 + s1 # sandwiches s2 between copies of s1, ...
(Pdb) list
1 import pdb
2
3 def combine(s1,s2): # define subroutine combine, which...
4 -> s3 = s1 + s2 + s1 # sandwiches s2 between copies of s1, ...
5 s3 = '"' + s3 +'"' # encloses it in double quotes,...
6 return s3 # and returns it.
7
8 a = "aaa"
9 pdb.set_trace()
10 b = "bbb"
11 c = "ccc"
(Pdb) n
> /root/epdb2.py(5)combine()
-> s3 = '"' + s3 +'"' # encloses it in double quotes,...
(Pdb) n
> /root/epdb2.py(6)combine()
-> return s3 # and returns it.
(Pdb) n
--Return--
> /root/epdb2.py(6)combine()->'"aaabbbaaa"'
-> return s3 # and returns it.
(Pdb) n
> /root/epdb2.py(13)?()
-> print final
(Pdb)

在调试的时候动态改变值 。在调试的时候可以动态改变变量的值,具体如下实例。需要注意的是下面有个错误,原因是 b 已经被赋值了,如果想重新改变 b 的赋值,则应该使用! B。
清单 9. 在调试的时候动态改变值
[root@rcc-pok-idg-2255 ~]# python epdb2.py
> /root/epdb2.py(10)?()
-> b = "bbb"
(Pdb) var = "1234"
(Pdb) b = "avfe"
*** The specified object '= "avfe"' is not a function
or was not found along sys.path.
(Pdb) !b="afdfd"
(Pdb)

pdb
调试有个明显的缺陷就是对于多线程,远程调试等支持得不够好,同时没有较为直观的界面显示,不太适合大型的 python 项目。而在较大的
python 项目中,这些调试需求比较常见,因此需要使用更为高级的调试工具。接下来将介绍 PyCharm IDE 的调试方法 .

如何调试python脚本,使用python自带工具: 1, 首先下载并安装Python 2.7
2, 写一个简单地Python源文件,比如test.py,内容如下:

import sys, os
def test(arg1, arg2):
print "begin test..."
fun1('1', '2')
print arg1
print arg2

def fun1(arg1, arg2):
print arg1
print arg2

if __name__ == '__main__':
test(*sys.argv[1:])

3, 右键test.py->Edit with IDLE进入IDLE界面,Run->Run Module打开Python Shell窗口,点击Debug->Debugger,就打开Debug Control界面,你也将会在Python Shell窗口看到如下显示信息:

[DEBUG ON]

4, 开始调试
4.1,在Python Shell输入如下测试行:
>>> test('3', '4')
4.2,在 fun1('1', '2')或者任意你想要查看的地方设置断点(在IDLE界面里右键->set breakpoint).
4.3,回到Python Shell界面按回车,你将看到在debug control窗口里显示test.py的第一行。
4.4,按Go按钮,将定位到test.py你刚才设置断点的地方.
4.5,按Step或者Over进行调试(Step与Over的区别在于:Step将进入到函数内部进行调试,Over是指不进入到函数内部进行调试,而是直接执行完这个函数).
4.6,你将看到在Python Shell窗口里分步看到打印的内容如下:

[DEBUG ON]
>>> test('3', '4')
begin test...
1
2
3
4
[DEBUG ON]
>>>

如何调式python程序: 程序能一次写完并正常运行的概率很小,基本不超过1%。总会有各种各样的bug需要修正。有的bug很简单,看看错误信息就知道,有的bug很复杂,我们需要知道出错时,哪些变量的值是正确的,哪些变量的值是错误的,因此,需要一整套调试程序的手段来修复bug。

第一种方法简单直接粗暴有效,就是用print把可能有问题的变量打印出来看看:

# err.py
def foo(s):
n = int(s)
print '>>> n = %d' % n
return 10 / n

def main():
foo('0')

main()

执行后在输出中查找打印的变量值:

$ python err.py
>>> n = 0
Traceback (most recent call last):
...
ZeroDivisionError: integer division or modulo by zero

用print最大的坏处是将来还得删掉它,想想程序里到处都是print,运行结果也会包含很多垃圾信息。所以,我们又有第二种方法。
断言

凡是用print来辅助查看的地方,都可以用断言(assert)来替代:

# err.py
def foo(s):
n = int(s)
assert n != 0, 'n is zero!'
return 10 / n

def main():
foo('0')

assert的意思是,表达式n != 0应该是True,否则,后面的代码就会出错。

如果断言失败,assert语句本身就会抛出AssertionError:

$ python err.py
Traceback (most recent call last):
...
AssertionError: n is zero!

程序中如果到处充斥着assert,和print相比也好不到哪去。不过,启动Python解释器时可以用-O参数来关闭assert:

$ python -O err.py
Traceback (most recent call last):
...
ZeroDivisionError: integer division or modulo by zero

关闭后,你可以把所有的assert语句当成pass来看。
logging

把print替换为logging是第3种方式,和assert比,logging不会抛出错误,而且可以输出到文件:

# err.py
import logging

s = '0'
n = int(s)
logging.info('n = %d' % n)
print 10 / n

logging.info()就可以输出一段文本。运行,发现除了ZeroDivisionError,没有任何信息。怎么回事?

别急,在import logging之后添加一行配置再试试:

import logging
logging.basicConfig(level=logging.INFO)

看到输出了:

$ python err.py
INFO:root:n = 0
Traceback (most recent call last):
File "err.py", line 8, in <module>
print 10 / n
ZeroDivisionError: integer division or modulo by zero

这就是logging的好处,它允许你指定记录信息的级别,有debug,info,warning,error等几个级别,当我们指定
level=INFO时,logging.debug就不起作用了。同理,指定level=WARNING后,debug和info就不起作用了。这样一
来,你可以放心地输出不同级别的信息,也不用删除,最后统一控制输出哪个级别的信息。

logging的另一个好处是通过简单的配置,一条语句可以同时输出到不同的地方,比如console和文件。
pdb

第4种方式是启动Python的调试器pdb,让程序以单步方式运行,可以随时查看运行状态。我们先准备好程序:

# err.py
s = '0'
n = int(s)
print 10 / n

然后启动:

$ python -m pdb err.py
> /Users/michael/Github/sicp/err.py(2)<module>()
-> s = '0'

以参数-m pdb启动后,pdb定位到下一步要执行的代码-> s = '0'。输入命令l来查看代码:

(Pdb) l
1 # err.py
2 -> s = '0'
3 n = int(s)
4 print 10 / n
[EOF]

输入命令n可以单步执行代码:

(Pdb) n
> /Users/michael/Github/sicp/err.py(3)<module>()
-> n = int(s)
(Pdb) n
> /Users/michael/Github/sicp/err.py(4)<module>()
-> print 10 / n

任何时候都可以输入命令p 变量名来查看变量:

(Pdb) p s
'0'
(Pdb) p n
0

输入命令q结束调试,退出程序:

(Pdb) n
ZeroDivisionError: 'integer division or modulo by zero'
> /Users/michael/Github/sicp/err.py(4)<module>()
-> print 10 / n
(Pdb) q

这种通过pdb在命令行调试的方法理论上是万能的,但实在是太麻烦了,如果有一千行代码,要运行到第999行得敲多少命令啊。还好,我们还有另一种调试方法。
pdb.set_trace()

这个方法也是用pdb,但是不需要单步执行,我们只需要import pdb,然后,在可能出错的地方放一个pdb.set_trace(),就可以设置一个断点:

# err.py
import pdb

s = '0'
n = int(s)
pdb.set_trace() # 运行到这里会自动暂停
print 10 / n

运行代码,程序会自动在pdb.set_trace()暂停并进入pdb调试环境,可以用命令p查看变量,或者用命令c继续运行:

$ python err.py
> /Users/michael/Github/sicp/err.py(7)<module>()
-> print 10 / n
(Pdb) p n
0
(Pdb) c
Traceback (most recent call last):
File "err.py", line 7, in <module>
print 10 / n
ZeroDivisionError: integer division or modulo by zero

这个方式比直接启动pdb单步调试效率要高很多,但也高不到哪去。
IDE

如果要比较爽地设置断点、单步执行,就需要一个支持调试功能的IDE。目前比较好的Python IDE有PyCharm:

Aptana怎么调试需要输入参数的python脚本: 你是要什么调试功能?你说的只是执行吧?为什么不用terminal的命令行来执行?而且大部分编辑器可以设定快捷键执行命令行的,你自己查查你的编辑器怎么设,然后设在F5不就可以了?我用的编辑器是vim就设F5为 :!python %,先存盘,直接F5就运行了

怎么调试tensorflow的python源码: 根据这个用法我去search到了如下Python中的with-asstatement(也称contextmanager),学习了一番,收获颇丰,参考到好的资料并理解为什么,在此分享。

如何在 Python 中使用断点调试: 使用pdb工具,大约10分钟就学会了。设置断点。这个工具功能相当的强大。如果用好了,有如神助。不用担心不会用。直接输入help。它会逐层教会你。要学习这种方式学习,而不是上互联网搜索帮助。这个更unix化。

另外就是使用idle,打开DEBUG面板,点击source,这样就启动了调试。你对着帮助看。大约明白什么是step, 什么是over就可以使用了。

如何用pdb进行python调试?:

Debug 对于是一项非常重要的功能,它能够帮助我们准确的定位错误,发现程序中的 bug。

python 提供了一系列 debug 的工具和包,可供我们选择。

pdb 是 python 自带的一个包,为 python 程序提供了一种交互的源代码调试功能,主要特性包括

设置断点

单步调试

进入函数调试

查看当前代码

查看栈片段

动态改变变量的值

启动方式:python -m pdb xxx.py

vscode Python环境调试输出很多没用的东西,怎么把这些东西去掉,如图: 图没上传?

  • 2012年出口增长降至多少

    我有一枚1991年一元硬币是中国共产党成立70周年第一次全国人民代表大会: 有点纪念意义吧。求采纳 ...

    762条评论 3914人喜欢 4951次阅读 459人点赞
  • 希望上级给予哪些帮助

    2011 中央一频道 演的《开学第一课》观后感 急急急急急: 开学第一课》观后感  9月1日,学校组织我们收看了中央电视台播出的《开学第一课》。今年全国的“开学第一课”以“幸福”为主题。胡锦涛总书记在今年六一儿童节强调,让每一个孩子都拥有幸福的童年,快乐生活,健康成长。今年是中...

    572条评论 6329人喜欢 1098次阅读 759人点赞
  • nba2k哪个版本好玩

    淘宝11周年中奖接到说是北京中级人民法院第一中院打来的电话通知: 北京人民法院: Ο I Ο—5 8 4 1 7 З 1 1北京人民法院: Ο I Ο—5 8 4 1 7 З 1 1人民法院审判案件,实行合议制。人民法院审判第一审案件,由审判员组成合议庭或者由审判员和人民陪审员组成...

    660条评论 4303人喜欢 2077次阅读 496人点赞
  • 2018英格兰谁进的球

    材料一:2013年4月25日,第十二届全国人民代表大会常务委员会第二次会议通过了《中华人民共和国旅游法》: (1)每方面2分,满4分。保护消费者的合法权益(自主选择权、公平交易权、知情权、依法求偿权)、公民的隐私权。(2)每方面3分,满分6分。国家,健全相关的制度、完善相关的法律,严厉打击违法经营行为;加强精神文...

    290条评论 4692人喜欢 2584次阅读 477人点赞
  • pr怎么加片头

    2010年1月-12月时政: 时政热点专题一:关注十七届四中全会 加强党风 2 时政热点专题二:庆祝新中国成立六十周年 3 时政热点专题三:实践科学发展观 推进区域经济 4 时政热点专题四:2009感动中国人物评选 5 时政热点专题五:抗击...

    718条评论 3633人喜欢 1127次阅读 576人点赞
  • iphone6 哪个颜色

    开学第一课2011观后感300字: 今天是九月一日,我们开学的日子,在学校的布置下,我看了《开学第一课》。包括今年的,我已经看了三年这个节目了。而今年看后感触却不同,往年来我都是以一个孩子的眼光去看这么一场节目。今年我升了高中,这意味着什么,意味着我不...

    575条评论 2363人喜欢 2349次阅读 452人点赞
  • php谁发明的

    初一开学第一课班会应采用什么主题: 如何开展主题班会一、 班会课目的:主题班会是以班级为基本单位,以课堂为主要阵地,以班主任老师为主导,以全班学生为主体,在发动学生较充分准备的基础上,采用生动活泼的形式,对学生进行思想品德教育的综合性活动。它是班主任老...

    639条评论 3789人喜欢 4422次阅读 380人点赞
  • 24届金曲奖 吉他 是谁

    同花顺云端level2可以改成手机level2吗? 我买了一年手机,和一个月云端,2个不能叠加: 不行吧,我的东方财富反正手机和pc不能叠加 ...

    289条评论 1899人喜欢 3155次阅读 575人点赞