zoukankan      html  css  js  c++  java
  • python pdb模块

    参考文件http://pythonconquerstheuniverse.wordpress.com/category/Python-debugger/

    翻译不是一一对应

    Debug功能对于developer是非常重要的,python提供了相应的模块pdb让你可以在用文本编辑器写脚本的情况下进行debug. pdb是python debugger的简称。

    常用的一些命令如下:

     

    命令用途
    break 或 b 设置断点
    continue 或 c 继续执行程序
    list 或 l 查看当前行的代码段
    step 或 s 进入函数
    return 或 r 执行代码直到从当前函数返回
    exit 或 q 中止并退出
    next 或 n 执行下一行
    pp 打印变量的值
    help 帮助

    开始介绍如何使用pdb。

    使用的测试代码1: epdb1.py

    import pdb
    a = "aaa"
    pdb.set_trace()
    b = "bbb"
    c = "ccc"
    final = a + b + c
    print final
    关于set_trace()
    pdb.
    set_trace()

    Enter the debugger at the calling stack frame. This is useful to hard-code abreakpoint at a given point in a program, even if the code is not otherwisebeing debugged (e.g. when an assertion fails).

    1 开始调试:

    [root@rcc-pok-idg-2255 ~]#  python epdb1.py
    > /root/epdb1.py(4)?()
    -> b = "bbb"
    (Pdb) n
    > /root/epdb1.py(5)?()
    -> c = "ccc"
    (Pdb)
    > /root/epdb1.py(6)?()
    -> final = a + b + c
    (Pdb) list
      1     import pdb
      2     a = "aaa"
      3     pdb.set_trace()
      4     b = "bbb"
      5     c = "ccc"
      6  -> final = a + b + c
      7     print final
    [EOF]
    (Pdb)
    [EOF]
    (Pdb) n
    > /root/epdb1.py(7)?()
    -> print final
    (Pdb)

    1. 使用n+enter表示执行当前的statement,在第一次按下了n+enter之后可以直接按enter表示重复执行上一条debug命令。

    If you press ENTER without entering anything, pdb will re-execute the last command that you gave it.

    1. quit或者q可以退出当前的debug,但是quit会以一种非常粗鲁的方式退出程序,直接crash

    [root@rcc-pok-idg-2255 ~]#  python epdb1.py
    > /root/epdb1.py(4)?()
    -> b = "bbb"
    (Pdb) n
    > /root/epdb1.py(5)?()
    -> c = "ccc"
    (Pdb) q
    Traceback (most recent call last):
      File "epdb1.py", line 5, in ?
        c = "ccc"
      File "epdb1.py", line 5, in ?
        c = "ccc"
      File "/usr/lib64/python2.4/bdb.py", line 48, in trace_dispatch
        return self.dispatch_line(frame)
      File "/usr/lib64/python2.4/bdb.py", line 67, in dispatch_line
        if self.quitting: raise BdbQuit
    bdb.BdbQuit


    • 在使用过程中打印变量的值,可以直接使用p加上变量名,但是需要注意的是打印仅仅在当前的statement已经被执行了之后才能看到具体的值,否则会报 NameError: <exceptions.NameError 。。> 错误。

    [root@rcc-pok-idg-2255 ~]#  python epdb1.py
    > /root/epdb1.py(4)?()
    -> b = "bbb"
    (Pdb) n
    > /root/epdb1.py(5)?()
    -> c = "ccc"
    (Pdb) p b
    'bbb'
    (Pdb)
    'bbb'
    (Pdb) n
    > /root/epdb1.py(6)?()
    -> final = a + b + c
    (Pdb) p c
    'ccc'
    (Pdb) p final
    *** NameError: <exceptions.NameError instance at 0x1551b710>
    (Pdb) n
    > /root/epdb1.py(7)?()
    -> print final
    (Pdb) p final
    'aaabbbccc'
    (Pdb)

    使用c可以停止当前的debug使得程序继续执行。如果在下面的程序中继续有set_statement()的申明,则又会重新进入到debug的状态。
    [root@rcc-pok-idg-2255 ~]#  python epdb1.py
    > /root/epdb1.py(4)?()
    -> b = "bbb"
    (Pdb) n
    > /root/epdb1.py(5)?()
    -> c = "ccc"
    (Pdb) c
    aaabbbccc

    可以在代码print final之前再加上set_trace()验证。

    • 如果代码过程,在debug的时候不一定能记住当前的代码快,则可以通过使用list或者l命令在显示。list会用箭头->指向当前debug的语句

    [root@rcc-pok-idg-2255 ~]#  python epdb1.py
    > /root/epdb1.py(4)?()
    -> b = "bbb"
    (Pdb) list
      1     import pdb
      2     a = "aaa"
      3     pdb.set_trace()
      4  -> b = "bbb"
      5     c = "ccc"
      6     final = a + b + c
      7     pdb.set_trace()
      8     print final
    [EOF]
    (Pdb) c
    > /root/epdb1.py(8)?()
    -> print final
    (Pdb) list
      3     pdb.set_trace()
      4     b = "bbb"
      5     c = "ccc"
      6     final = a + b + c
      7     pdb.set_trace()
      8  -> print final
    [EOF]
    (Pdb)

    对于使用函数的情况下进行debug:

     epdb2.py --import pdb
    
    def combine(s1,s2):      # define subroutine combine, which...
        s3 = s1 + s2 + s1    # sandwiches s2 between copies of s1, ...
        s3 = '"' + s3 +'"'   # encloses it in double quotes,...
        return s3            # and returns it.
    
    a = "aaa"
    pdb.set_trace()
    b = "bbb"
    c = "ccc"
    final = combine(a,b)
    print final


    如果直接使用n进行debug则到final=combine这句的时候会将其当做普通的赋值语句处理,进入到print final。如果想要对函数进行debug如何处理?可以直接使用s进入函数块。

    [root@rcc-pok-idg-2255 ~]# python epdb2.py
    > /root/epdb2.py(10)?()
    -> b = "bbb"
    (Pdb) n
    > /root/epdb2.py(11)?()
    -> c = "ccc"
    (Pdb) n
    > /root/epdb2.py(12)?()
    -> final = combine(a,b)
    (Pdb) s
    --Call--
    > /root/epdb2.py(3)combine()
    -> def combine(s1,s2):      # define subroutine combine, which...
    (Pdb) n
    > /root/epdb2.py(4)combine()
    -> s3 = s1 + s2 + s1    # sandwiches s2 between copies of s1, ...
    (Pdb) list
      1     import pdb
      2
      3     def combine(s1,s2):      # define subroutine combine, which...
      4  ->     s3 = s1 + s2 + s1    # sandwiches s2 between copies of s1, ...
      5         s3 = '"' + s3 +'"'   # encloses it in double quotes,...
      6         return s3            # and returns it.
      7
      8     a = "aaa"
      9     pdb.set_trace()
     10     b = "bbb"
     11     c = "ccc"
    (Pdb) n
    > /root/epdb2.py(5)combine()
    -> s3 = '"' + s3 +'"'   # encloses it in double quotes,...
    (Pdb) n
    > /root/epdb2.py(6)combine()
    -> return s3            # and returns it.
    (Pdb) n
    --Return--
    > /root/epdb2.py(6)combine()->'"aaabbbaaa"'
    -> return s3            # and returns it.
    (Pdb) n
    > /root/epdb2.py(13)?()
    -> print final
    (Pdb)

    如果不想在函数里单步调试可以在断点出直接按r退出到调用的地方。


    在调试的时候动态改变值 。注意下面有个错误,原因是b已经被赋值了,如果想重新改变b的赋值,则应该使用!b

    [root@rcc-pok-idg-2255 ~]# python epdb2.py
    > /root/epdb2.py(10)?()
    -> b = "bbb"
    (Pdb) var = "1234"
    (Pdb) b = "avfe"
    *** The specified object '= "avfe"' is not a function
    or was not found along sys.path.

    (Pdb) !b="afdfd"
    (Pdb)

    再贴一篇好文章:http://onlamp.com/pub/a/python/2005/09/01/debugger.html?page=1

    Debugger Module Contents

    The pdb module contains the debugger. pdb containsone class, Pdb, which inherits from bdb.Bdb. Thedebugger documentation mentions six functions, which create an interactivedebugging session:

    pdb.run(statement[, globals[, locals]])
    pdb.runeval(expression[, globals[, locals]])
    pdb.runcall(function[, argument, ...])
    pdb.set_trace()
    pdb.post_mortem(traceback)
    pdb.pm()

    All six functions provide a slightly different mechanism for dropping a userinto the debugger.

    pdb.run(statement[, globals[, locals]])

    pdb.run() executes the string statement under thedebugger's control. Global and local dictionaries are optional parameters:

    #!/usr/bin/env python
    
    import pdb
    
    def test_debugger(some_int):
        print "start some_int>>", some_int
        return_int = 10 / some_int
        print "end some_int>>", some_int
        return return_int
    
    if __name__ == "__main__":
        pdb.run("test_debugger(0)")

    pdb.runeval(expression[,globals[, locals]])

    pdb.runeval() is identical to pdb.run(), exceptthat pdb.runeval() returns the value of the evaluated stringexpression:

    #!/usr/bin/env python
    
    import pdb
    
    def test_debugger(some_int):
        print "start some_int>>", some_int
        return_int = 10 / some_int
        print "end some_int>>", some_int
        return return_int
    
    if __name__ == "__main__":
        pdb.runeval("test_debugger(0)")

    pdb.runcall(function[,argument, ...])

    pdb.runcall() calls the specified function andpasses any specified arguments to it:

    #!/usr/bin/env python
    
    import pdb
    
    def test_debugger(some_int):
        print "start some_int>>", some_int
        return_int = 10 / some_int
        print "end some_int>>", some_int
        return return_int
    
    if __name__ == "__main__":
        pdb.runcall(test_debugger, 0)

    pdb.set_trace()

    pdb.set_trace() drops the code into the debugger when executionhits it:

    #!/usr/bin/env python
    
    import pdb
    
    def test_debugger(some_int):
        pdb.set_trace()
        print "start some_int>>", some_int
        return_int = 10 / some_int
        print "end some_int>>", some_int
        return return_int
    
    if __name__ == "__main__":
        test_debugger(0)

    pdb.post_mortem(traceback)

    pdb.post_mortem() performs postmortem debugging of thespecified traceback:

    #!/usr/bin/env python
    
    import pdb
    
    def test_debugger(some_int):
        print "start some_int>>", some_int
        return_int = 10 / some_int
        print "end some_int>>", some_int
        return return_int
    
    if __name__ == "__main__":
        try:
            test_debugger(0)
        except:
            import sys
            tb = sys.exc_info()[2]
            pdb.post_mortem(tb)

    pdb.pm()

    pdb.pm() performs postmortem debugging of the tracebackcontained in sys.last_traceback:

    #!/usr/bin/env python
    
    import pdb
    import sys
    
    def test_debugger(some_int):
        print "start some_int>>", some_int
        return_int = 10 / some_int
        print "end some_int>>", some_int
        return return_int
    
    def do_debugger(type, value, tb):
        pdb.pm()
    
    if __name__ == "__main__":
        sys.excepthook = do_debugger
        test_debugger(0)
  • 相关阅读:
    ruby 二进制转十进制 Integer("0b101") = 5
    开始菜单和我的文档的我的图片及我的音乐变成 my pictrues 正常图标了
    ruby watir 莫名其妙的错误
    Excel SaveAS是去掉提示框
    apache && jboss安装
    ruby require include的区别
    ruby控制鼠标
    This error is raised because the column 'type' is reserved for storing the class in case of inheritance
    用正则表达式限制文本框只能输入数字,小数点,英文字母,汉字等各类代码
    ASP.NET 如何动态修改 Header 属性如添加 Meta 标签 keywords description!
  • 原文地址:https://www.cnblogs.com/qinduanyinghua/p/7152905.html
Copyright © 2011-2022 走看看