当前位置: 首页 > 后端技术 > Python

Python也有pdb

时间:2023-03-25 21:46:58 Python

C和gdb,Python也有pdb。写过C语言的同学一定怀念(读者:?)gdb调试器。使用gdb,可以在程序运行过程中随意暂停进程和查看变量。很多时候,我们不得不依靠调试器来帮助我们简单地分析无法定位的代码流和日志信息;可以说有了调试器,程序员就是彻头彻尾的代码世界之神。当然,Python也不示弱。也有这样一座通天塔,能让人升天01——但必须承认,现代IDE集成的图形化调试功能已经很不错了。总的来说,使用命令行工具的场景并不多。但是,确实有图形化IDE无法使用的情况,所以对pdb工具稍微了解一下还是很有必要的。毕竟,谁也不知道,它可能会被扔进什么样的环境中。呵呵,pdb是作为解释型语言使用的,Python调试工具的使用毕竟和gdb还是有区别的。比如Python调试不需要任何符号表之类的。毕竟Python虚拟机执行的逻辑也是有自己的符号的。正是因为Python的特殊性,所有的pdb其实都有两种不同的使用方式,即侵入式和非侵入式。其实从字面上理解这两种方法的用法是很容易理解的。以此类推,脑机接口也分为侵入式和非侵入式。侵入式是指将电极和芯片植入大脑皮层,“侵入”人体;非侵入性手段收集颅骨外的脑电波进行分析。同样,侵入式pdb调用是将调用pdb的代码直接写入Python脚本;非侵入式的是在命令行调用pdb,执行相应的调试脚本。侵入式pdb的使用方法如下代码所示,在代码中间插入一行调用:importpdb;#pdb.set_trace()a="just"b="do"pdb.set_trace()c=['p','y','t','h','o','n']print(a)运行脚本,会进入这样一个交互界面:D:\000-GitHub\python-examples\xuanyuanyulong\2020-11-04-python-pdb>pythontest_pdb_intrusive.py>d:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py(21)<模块>()->c=['p','y','t','h','o','n'](pdb)这里已经启动了pdb,并且在打印内容中->c=['p','y','t','h','o','n']的行首的箭头表示当前程序执行流程已经到了这行代码。如果继续执行,这一行会先执行。Non-intrusivepdb学习起来稍微简单一些,最大的优点是不需要改代码。我们在控制台执行如下命令:D:\000-GitHub\python-examples\xuanyuanyulong\2020-11-04-python-pdb>python-mpdbtest_pdb_intrusive.py>d:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py(1)<模块>()->importpdb;#pdb.set_trace()(Pdb)可以看到,通过这种方式,可以进入调试和程序执行流停止在程序的开头。通过分析进入调试时代码执行流程的位置,我们可以发现,侵入式插入pdb.set_trace()调用相当于从命令行启动pdb,然后在这个调用的下一行打断点,并且然后直接运行程序。简单命令gdb中有一些常用的简单命令。这一节,阿江就带大家熟悉一下,后面再深入探讨。h(elp)在pdb界面输入h或help命令,列出pdb支持的各种命令:(pdb)hDocumentedcommands(typehelp):========================================EOFcdhlistqrvundisplayacldebughelpllquitsuntaliascleardisableignorelonglistrsourceuntillargscommandsdisplayinteractnrestartstepupbconditiondownjnextreturntbreakwbreakcontenablejumppretvaluwhatisbtcontinueexitlpprununaliaswhere其他帮助主题:===========================execpdb在pdb之后将一个命令作为参数,你可以进一步看到相应的指令:(pdb)hhh(elp)不带参数,打印可用命令列表。使用命令名称作为参数,打印有关该命令的帮助。“helppdb”显示完整的pdb文档。“helpexec”给出帮助p上!命令。相信我,help实际上是pdb中最重要的命令。你可以忘记其他一切,但你必须记住帮助。在以结果为导向的职场生活中也是如此。遇到问题要及时求助~l(ist)打印当前文件的源代码。如果没有参数,默认打印当前行前后共11行代码。如果继续执行这条命令,它将继续打印最多11行代码,直到遇到文件结束符EOF。使用。作为参数的限制比较多,只会打印当前行前后的11行代码。(Pdb)l1->导入pdb;#pdb.set_trace()234defaddStr(a,b):5returna+b68return''.join(l)910defgetSlogan(a,b,c):11result=addStr(a,b)+mergeChar(c)当指定两个参数时,打印这段区间的代码:(Pdb)l3,734defaddStr(a,b):5returna+b67->defmergeChar(l:list):当第二个参数b小于第一个参数a时,表示“从a行开始,继续打印b行”,也就是一共打印(1+b)行:(Pdb)l7,37->defmergeChar(l:list):8return''.join(l)910defgetSlogan(a,b,c):p/pp打印一个对象的值。不同的是pp调用了pprint函数,打印出来更漂亮。(Pdb)pa'just'(Pdb)paddStr!使用!在pdb环境中执行一般的Python语句。通常我们可以用它来改变一个变量的值——除此之外,调试器还能如何让你成为上帝呢?还有比这更随意的吗?一般来说,这个!其实可以省略,但是当要执行的语句开头的单词和pdb已有的命令冲突时,会得不到预期的结果,所以建议加上。这个使用方法!引导命令与vim编辑器的逻辑非常相似,可以类比为内存。不熟悉的读者可以忽略。(pdb)!a="python"(Pdb)pa'python'r(eturn)在pdb中,r和return的意思是一样的,即“运行当前函数直到它返回”。在这一点上,pdb和gdb中r的含义是不一样的。读者不必关心run/restart是指重新运行当前调试的程序。使用该命令,可以为需要传入参数的脚本传入所需的参数。格式与命令行执行脚本相同,只是将相应的python命令和脚本路径换成了run或restart。(pdb)runabcdkkkRestartingtest_pdb_intrusive.pywitharguments:test_pdb_intrusive.py>d:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py(1)()->导入pdb;#pdb.set_trace()(Pdb)!importsys(Pdb)psys.argv['test_pdb_intrusive.py','a','b','c','d','kkk']b(reak)查看/添加断点。没有参数时,列出当前存在的断点。(pdb)b21Breakpoint1atd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:21(Pdb)b17Breakpoint2atd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:17(Pdb)bNumTypeDispEnbWhere1breakpointkeepyesatd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:212breakpointkeepyesatd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:17同时重新运行通过运行并重启调试的程序不会清除现有断点:(pdb)runRestartingtest_pdb_intrusive.pywitharguments:test_pdb_intrusive.py>d:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py(1)<模块>()->importpdb;#pdb.set_trace()(Pdb)bNumTypeDispEnbWhere1breakpointkeepyesatd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:212breakpointkeepyesatd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:17cl(ear)有3种使用方式:1)类似于设置断点,清除特定文件特定行的断点;2)列出要清除的断点号,以空格隔开;3)不带参数,清除所有断点下面一一演示:1)类似设置断点时,清除特定文件中特定行的断点(pdb)bNumTypeDispEnbWhere1breakpointkeepyesatd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:212断点在d:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:17(pdb)cleartest_pdb_intrusive.py:21(Pdb)bNumTypeDispEnbWhere2breakpointkeepyesatd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:172)断点待清除的number列出来,用空格隔开(pdb)b21Breakpoint3atd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:21(Pdb)b15Breakpoint4atd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:15(Pdb)bNumTypeDispEnbWhere2breakpointkeepyesatd:\000-github\python-examples\轩辕御龙\2020-11-04-python-pdb\test_pdb_intrusive.py:173断点在d:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:214断点在d:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-保持是pdb\test_pdb_intrusive.py:15(Pdb)clear24Deletedbreakpoint2atd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:17Deletedbreakpoint4atd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:15(Pdb)bNumTypeDispEnbWhere3breakpointkeepyesatd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:213)不带参数,清除所有断点(Pdb)b17Breakpoint5atd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:17(Pdb)b15Breakpoint6atd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:15(Pdb)bNumTypeDispEnbWhere3断点保持在d:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:215断点在d:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py保持yes:176breakpointkeepyesatd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:15(Pdb)bNumTypeDispEnbWhere3breakpointkeepyesatd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:215断点在d:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\保持yestest_pdb_intrusive.py:176breakpointkeepyesatd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:15(Pdb)clear清除所有断点?yesDeletedbreakpoint3atd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:21Deletedbreakpoint5atd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:17删除断点6atd:\000-github\python-examples\xuanyuanyulong\2020-11-04-python-pdb\test_pdb_intrusive.py:15(pdb)b好了停停,感觉pdb写之前是不是有多少东西,没想到写了这么多,直到发现这么少的量居然有这么多的内容,今天又熬夜了。。。summarypdb的内容竟然是这样的内容丰富,还有很多本文没有涉及的内容。再写一篇补充一下。软件调试其实是一个很有趣的知识,当然也是一个很有用的知识。以上就是本次分享的全部内容。想了解更多python知识,请前往公众号:Python编程学习圈,发“J”免费领取,每日干货分享