Bla*_*man 163 python debugging
在Java/C#中,您可以轻松地逐步执行代码以跟踪可能出错的内容,而IDE使此过程非常用户友好.
你能以类似的方式追踪python代码吗?
小智 234
是! 有一个Python调试器pdb只是为了做到这一点!
您可以pdb使用pdb myscript.py或启动Python程序python -m pdb myscript.py.
然后可以发布一些命令,这些命令在pdb页面上记录.
一些有用的要记住的是:
b:设置断点c:继续调试,直到遇到断点s:单步执行代码n:转到下一行代码l:列出当前文件的源代码(默认值:11行,包括正在执行的行)u:向上导航堆栈框架d:向下导航堆栈框架p:在当前上下文中打印表达式的值如果您不想使用命令行调试器,某些像Pydev这样的IDE 会有一个GUI调试器.
akD*_*akD 45
第一步是让Python解释器进入调试模式.
A.从命令行
最直接的方式,从命令行运行python解释器
$ python -m pdb scriptName.py
> .../pdb_script.py(7)<module>()
-> """
(Pdb)
Run Code Online (Sandbox Code Playgroud)
B.在口译员内
在开发早期版本的模块并进行迭代实验时.
$ python
Python 2.7 (r27:82508, Jul 3 2010, 21:12:11)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pdb_script
>>> import pdb
>>> pdb.run('pdb_script.MyObj(5).go()')
> <string>(1)<module>()
(Pdb)
Run Code Online (Sandbox Code Playgroud)
C.来自您的计划
对于一个大项目和长时间运行的模块,可以使用import pdb和set_trace()从程序内部开始调试, 如下所示:
#!/usr/bin/env python
# encoding: utf-8
#
import pdb
class MyObj(object):
count = 5
def __init__(self):
self.count= 9
def go(self):
for i in range(self.count):
pdb.set_trace()
print i
return
if __name__ == '__main__':
MyObj(5).go()
Run Code Online (Sandbox Code Playgroud)
逐步调试以进入更内部
执行下一个语句...用"n"(下一个)
使用ENTER重复上一个调试命令
全部退出...用"q"(退出)
打印变量值...用"p"(打印)
a) pa
关闭(Pdb)提示符... "c"(继续)
看看你在哪里......用"l"(列表)
步入子程序......用"s"(步入)
继续...但只是到当前子程序结束...用"r"(返回)
分配新值
a) !b ="B"
设置断点
a) 打破亚麻布
b) 中断functionname
c) break filename:linenumber
临时断点
a) tbreak linenumber
条件断点
a) 打破亚麻,状况
注意:**所有这些命令都应该从**pdb执行
如需深入了解,请参阅: -
https://pythonconquerstheuniverse.wordpress.com/2009/09/10/debugging-in-python/
Sen*_*ran 37
python中有一个名为'pdb'的模块.在你的python脚本的顶部你做
import pdb
pdb.set_trace()
Run Code Online (Sandbox Code Playgroud)
然后你将进入调试模式.您可以使用's'来步骤,'n'跟随下一行,类似于您对'gdb'调试器所做的操作.
Eug*_*ash 15
从Python 3.7开始,您可以使用breakpoint()内置函数进入调试器:
foo()
breakpoint() # drop into the debugger at this point
bar()
Run Code Online (Sandbox Code Playgroud)
默认情况下,breakpoint()将导入pdb并调用pdb.set_trace()。但是,您可以通过sys.breakpointhook()和使用环境变量来控制调试行为PYTHONBREAKPOINT。
有关更多信息,请参见PEP 553。
ipdb将IPython功能添加到pdb中,提供了以下巨大改进:
就像pdg一样,与GDB相比,ipdb仍然远远不够完善和完全初级,但是与pdb相比已经有了很大的改进。
用法类似于pdb,只需使用以下命令进行安装:
python3 -m pip install --user ipdb
Run Code Online (Sandbox Code Playgroud)
然后添加到您要从中逐步调试的行:
__import__('ipdb').set_trace(context=21)
Run Code Online (Sandbox Code Playgroud)
您可能想从编辑器中为其添加快捷方式,例如,对于我拥有的Vim片段:
snippet ipd
__import__('ipdb').set_trace(context=21)
Run Code Online (Sandbox Code Playgroud)
这样我就可以输入,ipd<tab>并且它会扩展到断点。dd由于所有内容都包含在一行中,因此删除它很容易。
context=21增加了上下文行的数量,如下所述:在调试时如何使ipdb显示更多上下文行?
另外,您也可以从头开始调试程序:
ipdb3 main.py
Run Code Online (Sandbox Code Playgroud)
但是您通常不想这样做,因为:
或者,就像在原始pdb 3.2+中一样,您可以从命令行设置一些断点:
ipdb3 -c 'b 12' -c 'b myfunc' ~/test/a.py
Run Code Online (Sandbox Code Playgroud)
虽然-c c由于某种原因而损坏了:https : //github.com/gotcha/ipdb/issues/156
python -m module在以下位置询问了调试:如何从命令行调试使用python -m运行的Python模块?由于Python 3.7可以通过以下方式完成:
python -m pdb -m my_module
Run Code Online (Sandbox Code Playgroud)
与GDB相比,pdb和ipdb严重缺少的功能:
ipdb的烦恼:
在Ubuntu 16.04,ipdb == 0.11,Python 3.5.2。中进行了测试
Python Tutor是一款面向新手的在线单步调试器。您可以在编辑页面输入代码,然后单击“可视化执行”开始运行。
除其他外,它支持:
但是它也不支持很多东西,例如:
io.StringIO和io.BytesIO代替:演示breakpoint()3.7+ 可以为您做什么。我已经安装了ipdb和pdbpp,它们都是增强的调试器,通过
pip install pdbpp
pip install ipdb
Run Code Online (Sandbox Code Playgroud)
我的测试脚本实际上没有做太多事情,只是调用breakpoint().
#test_188_breakpoint.py
myvars=dict(foo="bar")
print("before breakpoint()")
breakpoint() #
print(f"after breakpoint myvars={myvars}")
Run Code Online (Sandbox Code Playgroud)
Breakpoint() 链接到PYTHONBREAKPOINT环境变量。
bash您可以像往常一样通过设置变量
export PYTHONBREAKPOINT=0
这将关闭断点(),它不执行任何操作(只要您没有修改,sys.breakpointhook()这超出了本答案的范围)。
程序的运行如下所示:
(venv38) myuser@explore$ export PYTHONBREAKPOINT=0
(venv38) myuser@explore$ python test_188_breakpoint.py
before breakpoint()
after breakpoint myvars={'foo': 'bar'}
(venv38) myuser@explore$
Run Code Online (Sandbox Code Playgroud)
没有停止,因为我禁用了断点。pdb.set_trace()做不到的事情!
现在,让我们取消设置PYTHONBREAKPOINT,这将使我们恢复正常的启用断点行为(仅当0非空时才禁用)。
(venv38) myuser@explore$ unset PYTHONBREAKPOINT
(venv38) myuser@explore$ python test_188_breakpoint.py
before breakpoint()
[0] > /Users/myuser/kds2/wk/explore/test_188_breakpoint.py(6)<module>()
-> print(f"after breakpoint myvars={myvars}")
(Pdb++) print("pdbpp replaces pdb because it was installed")
pdbpp replaces pdb because it was installed
(Pdb++) c
after breakpoint myvars={'foo': 'bar'}
Run Code Online (Sandbox Code Playgroud)
它停止了,但我实际上得到了pdbpp,因为它pdb在安装时完全替换了。如果我卸载pdbpp,我就会恢复正常pdb。
注意:标准pdb.set_trace()仍然会让我满意pdbpp
但我们还是打电话ipdb吧。这次,我们可以bash只为这一个命令设置环境变量,而不是设置环境变量。
(venv38) myuser@explore$ PYTHONBREAKPOINT=ipdb.set_trace py test_188_breakpoint.py
before breakpoint()
> /Users/myuser/kds2/wk/explore/test_188_breakpoint.py(6)<module>()
5 breakpoint()
----> 6 print(f"after breakpoint myvars={myvars}")
7
ipdb> print("and now I invoked ipdb instead")
and now I invoked ipdb instead
ipdb> c
after breakpoint myvars={'foo': 'bar'}
Run Code Online (Sandbox Code Playgroud)
本质上,当查看 $PYTHONBREAKPOINT 时,它的作用是:
from ipdb import set_trace # function imported on the right-most `.`
set_trace()
Run Code Online (Sandbox Code Playgroud)
同样,比普通的旧 pdb.set_trace() 聪明得多
假设我总是想要 ipdb,我会:
export它通过.profile或类似的。示例(pytest调试器经常会造成不愉快的夫妻):
(venv38) myuser@explore$ export PYTHONBREAKPOINT=ipdb.set_trace
(venv38) myuser@explore$ echo $PYTHONBREAKPOINT
ipdb.set_trace
(venv38) myuser@explore$ PYTHONBREAKPOINT=0 pytest test_188_breakpoint.py
=================================== test session starts ====================================
platform darwin -- Python 3.8.6, pytest-5.1.2, py-1.9.0, pluggy-0.13.1
rootdir: /Users/myuser/kds2/wk/explore
plugins: celery-4.4.7, cov-2.10.0
collected 0 items
================================== no tests ran in 0.03s ===================================
(venv38) myuser@explore$ echo $PYTHONBREAKPOINT
ipdb.set_trace
Run Code Online (Sandbox Code Playgroud)
我正在使用bashunder macos,任何 posix shell 的行为都基本相同。Windows(无论是 powershell 还是 DOS)可能具有不同的功能,尤其是PYTHONBREAKPOINT=<some value> <some command>仅为一个命令设置环境变量的功能。
| 归档时间: |
|
| 查看次数: |
212761 次 |
| 最近记录: |