使用pdb时如何忽略行?

2024-05-16 12:54:05 发布

您现在位置:Python中文网/ 问答频道 /正文

为了进行一些快速的Python调试,我偶尔会添加一行import pdb;pdb.set_trace()将我放入调试器。非常方便。但是,如果我想调试一个循环,它可能会运行很多次,很多次,它会失去它的有效性。我可以将c继续很多次,很多次,但是有没有一种方法可以删除/忽略这个硬编码的断点,这样我就可以让它完成了?在

我可以设置一个全局标志并有条件地运行它,但是这样我就失去了一行断点的“独立性”,也需要为每个pdb.set_trace()添加另一个标志。在


Tags: 方法import编码标志trace条件全局调试器
3条回答

你看了condition bpnumber了吗?您可以禁用断点,然后将其设为条件断点。或者,您可以使用breaktbreak使断点首先成为条件。可以在here找到详细信息。在

我的另一个答案是一种快速破解,而且并不完美(将禁用对set_trace的所有调用)。这里有一个更好的解决方案。在

我们定义了一个模块包装pdb。其中,set_trace是一个可调用的对象,维护一个禁用的调用方列表(由文件名/行号标识)。在

# 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()

在代码中,确保使用包装器:

^{pr2}$

要禁用当前set_trace-主叫线路时,请执行以下操作:

pdb.set_trace.disable_current()

注意事项:

  1. 我个人更喜欢ipdb,而不是pdb

  2. 当使用pdb时,由于实际调用pdb.set_trace的函数在包装中,中断时的当前帧将在其中。up命令将获得所需的to帧。如果使用ipdb(包装器中的实现确保在正确的位置中断),则不会发生这种情况。

  3. 当使用ipdb时,我发现它报告的调用者帧行号不一致。这意味着你第一次做pdb.set_trace.disable_current(),它可能无法容纳。如果下次坏了就再做一次——第二次就可以了。

  4. 一般来说,拥有自己的pdb包装对其他事情也很有用。我有自己的set_trace包装器,它可以避免在not sys.stdout.isatty时中断(如果进程没有连接到终端,或者当您将stdout重定向到文件/管道时,您永远不想中断)。也就是说,拥有自己的pdb包装并调用它的set_trace而不是{},这是一个很好的实践。

下面的方法将禁用当前运行中对set_trace的所有其他调用(即,从代码中的任何位置)。在

创建此noop_pdb下拉列表:

# noop_pdb.py
def set_trace(*args, **kwargs):
    pass

然后,一旦代码在实数pdb.set_trace中中断,并且希望禁用对set_trace的其余调用,请执行以下操作:

^{pr2}$

下一次口译员遇到这样的行时:

import pdb;pdb.set_trace()

它避免了重新导入内置的pdb,从而拿起了该插件。在

编辑:另一种不需要noop_pdb的方法是用noop替换{},而不是整个{}模块:pdb.set_trace = lambda: None

相关问题 更多 >