python条件调试断点—3.7 PEP 553之前版本的一行程序,其作用类似于Perl';s$DB::single=1
在PEP 553python条件调试断点—3.7 PEP 553之前版本的一行程序,其作用类似于Perl';s$DB::single=1,python,perl,debugging,breakpoints,conditional-execution,Python,Perl,Debugging,Breakpoints,Conditional Execution,在PEP 553breakpoint()实用程序之前的python版本中,建议使用什么方法添加(理想情况下是一行代码)代码,使其具有一个断点,该断点可以在某个条件下被忽略(例如,全局调试标志或args.debug标志) 在Perl中,我习惯于使用$DB::single=1;1;单行,我知道我可以安全地保留在代码中,并且不会影响perl code.pl的正常运行,除非显式调用perl-d code.pl。例如: my $a = 1; $DB::single=1;1; # breakpoint li
breakpoint()
实用程序之前的python版本中,建议使用什么方法添加(理想情况下是一行代码)代码,使其具有一个断点,该断点可以在某个条件下被忽略(例如,全局调试标志或args.debug标志)
在Perl中,我习惯于使用$DB::single=1;1;代码>单行,我知道我可以安全地保留在代码中,并且不会影响perl code.pl
的正常运行,除非显式调用perl-d code.pl
。例如:
my $a = 1;
$DB::single=1;1; # breakpoint line
my $b = 2;
print "$a $b\n";
如果我以:perl code.pl
的形式运行此代码,它将一直运行到完成。
如果我使用:perl-dcode.pl
运行此代码,则pdb
将在断点行停止(而不是在下一行使用my$b=2;
语句之前),因为它包含1$DB::single=1之后的code>语句代码>语句
同样,如果我写:
my $debug = 1;
my $a = 1;
$DB::single=$debug;1; # first breakpoint line
my $b = 2;
$DB::single=$debug;1; # second breakpoint line
print "$a $b\n";
# [...] Lots more code sprinkled with more of these
$DB::single=$debug;1; # n'th breakpoint line
然后我可以执行perl-dcode.pl
,它将在第一个断点行停止,然后在pdb
会话中,一旦我很高兴它不需要在任何其他地方停止,然后执行:$debug=0
,然后pdb
继续c
,这将使它不会在代码中的第二行或其他类似断点行停止
我如何在python中(PEP553之前的2.x和3.x版本)实现同样的效果,最好是在单行语句中
我知道PEP 553,除了必须显式设置PYTHONBREAKPOINT=0 python3.7 code.py
或注释掉breakpoint()
行的麻烦之外,它是这里问题的解决方案
我想到了如下选择:
import pdb; pdb.set_trace()
dummy=None;
pdb.set_trace()
下面的语句是为了实现与1相同的功能$DB::single=1后的同一行中的code>代码>在Perl中,这是让调试器停止在我放置断点的地方,而不是下一条语句。这样,如果中间有大量注释代码或文档,调试器就不会跳转到离断点很远的下一条语句
或使用以下条件:
if args.debug or debug:
import pdb; pdb.set_trace()
_debug=False; #args.debug=False
因此,如果我完成了脚本调试,我可以设置args.debug=False
或debug=False
,而不必触及代码中的所有断点。以下是使用当前目录中的.pdbrc
文件的简单方法:
t.py
def my_trace():
global debug
if debug:
import pdb; pdb.set_trace()
debug = True
a= 1
my_trace()
b = 2
c = 3
my_trace()
d = 4
.pdbrc:
r
$ python t.py
--Return--
> [...]/t.py(12)<module>()
-> b = 2
(Pdb) p a
1
(Pdb) p b
*** NameError: name 'b' is not defined
(Pdb) !debug=False
(Pdb) c
$
示例会话:
r
$ python t.py
--Return--
> [...]/t.py(12)<module>()
-> b = 2
(Pdb) p a
1
(Pdb) p b
*** NameError: name 'b' is not defined
(Pdb) !debug=False
(Pdb) c
$
$python t.py
--返回--
>[…]/t.py(12)()
->b=2
(Pdb)p a
1.
(Pdb)p b
***名称错误:未定义名称“b”
(Pdb)!调试=错误
(Pdb)c
$
设置条件断点
与perl相同,python可以与-d
一起运行,以设置调试标志:
$python--帮助
[...]
-d:解析器的调试输出;另外,PYTHONDEBUG=x
[...]
您可以在运行时通过sys.flags
检查其状态:
$python-d
Python 2.7.15+(默认值,2018年11月27日,23:36:35)
[GCC 7.3.0]在linux2上
有关详细信息,请键入“帮助”、“版权”、“信用证”或“许可证”。
>>>导入系统
>>>系统标志
系统标志(调试=1,py3k_警告=0,分区_警告=0,…)
#^在那里,就在前面
允许以下一个线性程序启用调试:
导入pdb,系统;pdb.set_trace()如果sys.flags[0]否则无
从调试器禁用条件断点
关于这一部分
[…]一旦我很高兴它不需要在任何其他地方停止,那么执行[something],这将使它不会在代码中的第二行或其他类似断点行停止
但它变得有点棘手,因为python不允许对它进行变异,甚至不允许创建它的实例:
导入系统
>>>sys.flags.debug=0#无变异。。。
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:只读属性
>>>键入(系统标志)(#。。。而且没有实例化
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:无法创建“sys.flags”实例
但就我所测试的而言,除非您使用其他标志运行python,否则以下功能可以在不改变程序其他行为的情况下停用后续跟踪:
导入系统;sys.flags=[0]*len(sys.flags)#甚至可以放在一行上
要获得一个稍微更健壮的猴子补丁,以防前一个补丁导致奇怪的bug,您需要有如下内容:
def untrace():
“”“在pdb会话中调用此函数以跳过仅调试的set_trace()调用”“”
进口稀土
导入系统
从集合导入namedtuple#与struct sequence具有相同的接口
sys.flags=namedtuple(
“系统标志”,
[m.group()用于re.FindItemer(r'\w{2,}',repr(sys.flags)[10:-1])中的m]
)(0,*系统标志[1:])
虽然这句话可以放在一行上,但可能有点太多了。您可以将此函数粘贴到计划使用它的.py
文件中,或者使用某种类型的utils.py
,在调试期间从中导入它,然后c(continue)应再次运行程序的其余部分:
(Pdb)导入UTIL;utils.untrace()
(Pdb)c
谢谢您的回答。似乎pdb跳转到导入pdb;pdb.set_trace()
当我运行脚本时,不要停留在my_trace()之外。你知道为什么吗?奇怪的是,它适合我(Python 3.7.1)。您是否将.pdbrc
保存在当前目录中?没有它和r
(return
)命令,它将无法工作!抱歉,我运行的是Python2.x而不是Python3.x。我现在可以使用您在使用Python3.4.3(旧的Ubuntu14.04笔记本电脑)时描述的行为。最后一件事是能够有一个单线等价物