gpt4 book ai didi

python 条件调试断点单行代码,适用于 3.7 PEP 553 之前的版本,其行为类似于 Perl 的 $DB::single=1

转载 作者:太空狗 更新时间:2023-10-29 17:07:24 28 4
gpt4 key购买 nike

在 PEP 553 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 -d code.plpdb 将在断点行停止(而不是在下一行之前使用 my $b = 2; 语句)因为它在 $DB::single=1; 语句之后包含一个 1; 语句;

同样,如果我写:

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 -d code.pl,它将在第一个断点行停止,然后在 pdb session 中,一旦我很高兴它会停止不需要在其他任何地方停止,然后执行:$debug = 0,然后pdb继续c,这样就不会停在第二个或代码中其他类似的断点行。

我怎样才能在 python(PEP 553 之前的 2.x 和 3.x)中实现相同的效果,最好是在单行语句中?

我知道 PEP 553,除了必须显式设置 PYTHONBREAKPOINT=0 python3.7 code.py 或注释掉 breakpoint() 行的麻烦,它是这里问题的解决方案。

我想到了以下选项:

import pdb; pdb.set_trace()
dummy=None;

pdb.set_trace() 下面的语句是为了让我可以在 $DB::single 之后的同一行中实现与 1; 相同的效果=1; 在 Perl 中,这是让调试器停止在我放置断点的地方,而不是下一条语句。这样一来,如果中间有大量注释代码或文档,调试器就不会跳转到远离断点的下一条语句。

或者像这样的条件:

if args.debug or debug:
import pdb; pdb.set_trace()
_debug=False; #args.debug=False

因此,如果我完成了脚本的调试,我可以设置 args.debug=Falsedebug=False 而不必触及代码。

最佳答案

设置条件断点

和perl一样,python可以用-d运行来设置调试标志:

$ python --help
[...]
-d : debug output from parser; also PYTHONDEBUG=x
[...]

您可以在运行时通过 sys.flags 检查其状态:

$ python -d
Python 2.7.15+ (default, Nov 27 2018, 23:36:35)
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.flags
sys.flags(debug=1, py3k_warning=0, division_warning=0, ...)
# ^ there it is, right at the front

这允许以下一行代码启用调试:

import pdb, sys; pdb.set_trace() if sys.flags[0] else None

从调试器中禁用条件断点

关于这部分

[...] once I am happy that it does not need stopping anywhere else, then execute [something] which will make it not stop at the second or other similar breakpoint lines in the code.

虽然它变得有点棘手,因为 python 不允许 the flags structure 的突变,甚至创建它的一个实例:

>>> import sys
>>> sys.flags.debug = 0 # no mutating ...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: readonly attribute
>>> type(sys.flags)() # ... and no instanciating
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: cannot create 'sys.flags' instances

但据我测试,除非您使用其他标志运行 python,否则以下方法可以在不改变程序的其他行为的情况下停用后续跟踪:

import sys; sys.flags = [0]*len(sys.flags)  # even fits onto a single line

对于一个稍微更健壮的猴子补丁,你应该使用它以防前一个导致奇怪的错误,你需要有这样的东西:

def untrace():
"""Call this function in the pdb session to skip debug-only set_trace() calls"""
import re
import sys
from collections import namedtuple # has the same interface as struct sequence
sys.flags = namedtuple(
'sys_flags',
[m.group() for m in re.finditer(r'\w{2,}', repr(sys.flags)[10:-1])]
)(0, *sys.flags[1:])

虽然此语句可以放在一行中,但它可能有点太多了。您可以将此函数粘贴到您计划使用它的 .py 文件中,或者有某种类型的 utils.py 在调试期间从中导入它,之后c(ontinue) 应该再次运行程序的其余部分:

(Pdb) import utils; utils.untrace()
(Pdb) c

关于python 条件调试断点单行代码,适用于 3.7 PEP 553 之前的版本,其行为类似于 Perl 的 $DB::single=1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56596274/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com