【问题标题】:Break on next output while running in debugger在调试器中运行时中断下一个输出
【发布时间】:2016-07-12 07:21:02
【问题描述】:

是否可以将我的调试器设置为在被调试的应用程序产生下一个控制台输出时中断?

我的应用程序正在打印一个奇怪的字符串,我需要弄清楚它来自哪里。搜索源代码发现太多可能的候选,字符串很通用。

【问题讨论】:

    标签: python debugging


    【解决方案1】:

    如果您使用的是 Python 3,只需定义一个自定义 print 函数,该函数通过 __builtins__ 调用原始函数并在该自定义函数中设置断点。您的代码将调用它而不是原始代码,而无需修改任何其他内容:

    def print(*args, **kwargs):
        # set debugger breakpoint here
        __builtins__.print(*args, **kwargs)
    
    # your code below can use print() normally
    

    当您完成调试后,只需再次删除或注释该覆盖函数即可。

    【讨论】:

    • @GingerPlusPlus 您的编辑不正确,没有builtins 对象,只有__builtins__,正如我在回答中所写的那样。我把它回滚了。
    • 我不知道 Py3 中有内置的 __builtins__ 模块,谢谢。但是,也有可导入的 builtins 模块。
    • @GingerPlusPlus 啊,好的。我不知道那个模块。但是您的编辑没有包含导入语句。
    【解决方案2】:

    Python 2.x 中,您可以通过将 sys.stdout 替换为满足文件接口的对象来拦截打印语句(想想鸭子打字)。一个简单的开始:

    import inspect
    import sys
    
    class OutputHook(object):
        def __init__(self, stdout):
            self._stdout = stdout
    
        def write(self, text):
            frame = inspect.currentframe(1)
            try:
                class_name = frame.f_locals['self'].__class__.__name__ + "."
            except KeyError:
                class_name = ""
            self._stdout.write("writing to sys.stdout at "
                               "{}{}() in line {}:\n{}\n".format(
                                   class_name,
                                   frame.f_code.co_name,
                                   frame.f_lineno,
                                   repr(text)))
    
    def test():
        print "BBB"
    
    class Test:
        def bla(self):
            print "Hello"
    
    sys.stdout = OutputHook(sys.stdout)
    
    print "aaa"
    test()
    Test().bla()
    

    你会得到输出:

    writing to sys.stdout at <module>() in line 33:
    'aaa'
    writing to sys.stdout at <module>() in line 33:
    '\n'
    writing to sys.stdout at test() in line 25:
    'BBB'
    writing to sys.stdout at test() in line 25:
    '\n'
    writing to sys.stdout at Test.bla() in line 29:
    'Hello'
    writing to sys.stdout at Test.bla() in line 29:
    '\n'
    

    您可以添加检查写入的文本是否是您的模式并启动调试器,或者只是中断,例如:

    if text.startwith("funny"):
        pdb.set_trace()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-10
      • 2019-09-17
      相关资源
      最近更新 更多