2024-05-16 12:54:05 发布
网友
为了进行一些快速的Python调试,我偶尔会添加一行import pdb;pdb.set_trace()将我放入调试器。非常方便。但是,如果我想调试一个循环,它可能会运行很多次,很多次,它会失去它的有效性。我可以将c继续很多次,很多次,但是有没有一种方法可以删除/忽略这个硬编码的断点,这样我就可以让它完成了?在
import pdb;pdb.set_trace()
c
我可以设置一个全局标志并有条件地运行它,但是这样我就失去了一行断点的“独立性”,也需要为每个pdb.set_trace()添加另一个标志。在
pdb.set_trace()
你看了condition bpnumber了吗?您可以禁用断点,然后将其设为条件断点。或者,您可以使用break或tbreak使断点首先成为条件。可以在here找到详细信息。在
condition bpnumber
break
tbreak
我的另一个答案是一种快速破解,而且并不完美(将禁用对set_trace的所有调用)。这里有一个更好的解决方案。在
set_trace
我们定义了一个模块包装pdb。其中,set_trace是一个可调用的对象,维护一个禁用的调用方列表(由文件名/行号标识)。在
pdb
# mypdb.py import inspect import sys try: import ipdb as PDB except ImportError: import pdb as PDB class SetTraceWrapper(object): def __init__(self): self.callers_disabled = set() self.cur_caller = None def __call__(self): self.cur_caller = self.get_caller_id() if self.cur_caller in self.callers_disabled: # already disabled for caller #print 'set_trace SKIPPED for %s' % ( self.cur_caller, ) return #print 'set_trace BREAKING for %s' % ( self.cur_caller, ) try: PDB.set_trace(sys._getframe().f_back) except TypeError: PDB.set_trace() def disable_current(self): #print 'set_trace DISABLING %s' % ( self.cur_caller, ) self.callers_disabled.add(self.cur_caller) def get_caller_id(self, levels_up = 1): f = inspect.stack()[levels_up + 1] return ( f[1], f[2] ) # filename and line number set_trace = SetTraceWrapper()
在代码中,确保使用包装器:
要禁用当前set_trace-主叫线路时,请执行以下操作:
pdb.set_trace.disable_current()
注意事项:
我个人更喜欢ipdb,而不是pdb
ipdb
当使用pdb时,由于实际调用pdb.set_trace的函数在包装中,中断时的当前帧将在其中。up命令将获得所需的to帧。如果使用ipdb(包装器中的实现确保在正确的位置中断),则不会发生这种情况。
pdb.set_trace
up
当使用ipdb时,我发现它报告的调用者帧行号不一致。这意味着你第一次做pdb.set_trace.disable_current(),它可能无法容纳。如果下次坏了就再做一次——第二次就可以了。
一般来说,拥有自己的pdb包装对其他事情也很有用。我有自己的set_trace包装器,它可以避免在not sys.stdout.isatty时中断(如果进程没有连接到终端,或者当您将stdout重定向到文件/管道时,您永远不想中断)。也就是说,拥有自己的pdb包装并调用它的set_trace而不是{},这是一个很好的实践。
not sys.stdout.isatty
下面的方法将禁用当前运行中对set_trace的所有其他调用(即,从代码中的任何位置)。在
创建此noop_pdb下拉列表:
noop_pdb
# noop_pdb.py def set_trace(*args, **kwargs): pass
然后,一旦代码在实数pdb.set_trace中中断,并且希望禁用对set_trace的其余调用,请执行以下操作:
下一次口译员遇到这样的行时:
它避免了重新导入内置的pdb,从而拿起了该插件。在
编辑:另一种不需要noop_pdb的方法是用noop替换{},而不是整个{}模块:pdb.set_trace = lambda: None
pdb.set_trace = lambda: None
你看了
condition bpnumber
了吗?您可以禁用断点,然后将其设为条件断点。或者,您可以使用break
或tbreak
使断点首先成为条件。可以在here找到详细信息。在我的另一个答案是一种快速破解,而且并不完美(将禁用对
set_trace
的所有调用)。这里有一个更好的解决方案。在我们定义了一个模块包装
pdb
。其中,set_trace
是一个可调用的对象,维护一个禁用的调用方列表(由文件名/行号标识)。在在代码中,确保使用包装器:
^{pr2}$要禁用当前
set_trace
-主叫线路时,请执行以下操作:注意事项:
我个人更喜欢
ipdb
,而不是pdb
当使用
pdb
时,由于实际调用pdb.set_trace
的函数在包装中,中断时的当前帧将在其中。up
命令将获得所需的to帧。如果使用ipdb
(包装器中的实现确保在正确的位置中断),则不会发生这种情况。当使用
ipdb
时,我发现它报告的调用者帧行号不一致。这意味着你第一次做pdb.set_trace.disable_current()
,它可能无法容纳。如果下次坏了就再做一次——第二次就可以了。一般来说,拥有自己的},这是一个很好的实践。
pdb
包装对其他事情也很有用。我有自己的set_trace
包装器,它可以避免在not sys.stdout.isatty
时中断(如果进程没有连接到终端,或者当您将stdout重定向到文件/管道时,您永远不想中断)。也就是说,拥有自己的pdb
包装并调用它的set_trace
而不是{下面的方法将禁用当前运行中对
set_trace
的所有其他调用(即,从代码中的任何位置)。在创建此
noop_pdb
下拉列表:然后,一旦代码在实数
^{pr2}$pdb.set_trace
中中断,并且希望禁用对set_trace
的其余调用,请执行以下操作:下一次口译员遇到这样的行时:
它避免了重新导入内置的
pdb
,从而拿起了该插件。在编辑:另一种不需要},而不是整个{}模块:
noop_pdb
的方法是用noop替换{pdb.set_trace = lambda: None
相关问题 更多 >
编程相关推荐