zoukankan      html  css  js  c++  java
  • 【Python】debug工具-pdb(转)

    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)
    计划、执行、每天高效的活着学着
  • 相关阅读:
    nginx与uwsgi介绍
    Pycharm快捷键
    短信和图片验证码
    linux部署Django脱坑指南
    面试题汇总(七)
    面试题汇总(六)
    面试题汇总(五)
    面试题汇总(四)
    面试题汇总(二)
    iOS Block的本质(四)
  • 原文地址:https://www.cnblogs.com/huxiaoyun90/p/4113532.html
Copyright © 2011-2022 走看看