Pythondebugging技巧

什么是debuggingPython的最佳技巧?

请不要只是列出一个特定的debugging器,不要说它实际上可以做什么。

有关

  • 什么是使我的Python代码第一次运行的好方法? – 这讨论了最小化错误

PDB

你可以使用pdb模块,在任何地方插入pdb.set_trace() ,它将作为一个断点。

 >>> import pdb >>> a="a string" >>> pdb.set_trace() --Return-- > <stdin>(1)<module>()->None (Pdb) pa 'a string' (Pdb) 

要继续执行,请使用c (或continue )。

可以使用pdb执行任意的Pythonexpression式。 例如,如果发现错误,则可以更正该代码,然后键入一个typesexpression式以在运行代码中具有相同的效果

ipdb是IPython的pdb版本。 它允许使用包含Tab完成function的所有IPythonfunction。

也可以将pdb设置为自动运行未捕获的exception。

Pydb被写为一个增强版的Pdb。 好处?

http://pypi.python.org/pypi/pudb ,一个基于控制台的全屏Pythondebugging器。

它的目标是在一个更轻量级和键盘友好的软件包中提供现代基于GUI的debugging器的所有优点。 PuDB允许你在你编写和testing的地方debugging代码 – 在terminal中。 如果你已经使用了基于DOS的Turbo Pascal或者C工具,但是PuDB的UI可能看起来很熟悉。

pudb截图

很好的debugging独立脚本,只需运行

 python -m pudb.run my-script.py 

如果您使用的是pdb,则可以为快捷方式定义别名。 我使用这些:

 # Ned's .pdbrc # Print a dictionary, sorted. %1 is the dict, %2 is the prefix for the names. alias p_ for k in sorted(%1.keys()): print "%s%-15s= %-80.80s" % ("%2",k,repr(%1[k])) # Print the instance variables of a thing. alias pi p_ %1.__dict__ %1. # Print the instance variables of self. alias ps pi self # Print the locals. alias pl p_ locals() local: # Next and list, and step and list. alias nl n;;l alias sl s;;l # Short cuts for walking up and down the stack alias uu u;;u alias uuu u;;u;;u alias uuuu u;;u;;u;;u alias uuuuu u;;u;;u;;u;;u alias dd d;;d alias ddd d;;d;;d alias dddd d;;d;;d;;d alias ddddd d;;d;;d;;d;;d 

logging

Python已经有了一个优秀的内置日志logging模块 。 您可能想在这里使用日志logging模板 。

日志模块可以让你指定一个重要的级别; 在debugging期间,您可以logging一切,而在正常操作期间,您可能只logging重要的事情。 你可以打开和closures的东西。

大多数人只是使用基本的打印语句进行debugging,然后删除打印语句。 最好留下他们,但禁用他们; 那么当你有另外一个bug的时候,你可以重新启用所有的东西,然后查看你的日志。

这可能是debugging需要快速执行任务的程序的最佳方式,例如在networking连接的另一端超时而消失之前需要响应的networking程序。 您可能没有足够的时间单步debugging器; 但是你可以让你的代码运行,logging下所有的东西,然后仔细检查日志,找出真正发生的事情。

编辑:模板的原始URL是: http : //aymanh.com/python-debugging-techniques

这个页面丢失了,所以我用保存在archive.org的快照的引用replace了它: http ://web.archive.org/web/20120819135307/http: //aymanh.com/python-debugging-techniques

如果它再次消失,这里是我提到的模板。 这是来自博客的代码; 我没有写。

 import logging import optparse LOGGING_LEVELS = {'critical': logging.CRITICAL, 'error': logging.ERROR, 'warning': logging.WARNING, 'info': logging.INFO, 'debug': logging.DEBUG} def main(): parser = optparse.OptionParser() parser.add_option('-l', '--logging-level', help='Logging level') parser.add_option('-f', '--logging-file', help='Logging file name') (options, args) = parser.parse_args() logging_level = LOGGING_LEVELS.get(options.logging_level, logging.NOTSET) logging.basicConfig(level=logging_level, filename=options.logging_file, format='%(asctime)s %(levelname)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S') # Your program goes here. # You can access command-line arguments using the args variable. if __name__ == '__main__': main() 

这是他如何使用上述的解释。 再一次,我没有得到这个功劳:


默认情况下,日志模块输出关键的错误和警告消息。 要改变这个以便打印所有级别,请使用:

 $ ./your-program.py --logging=debug 

要将日志消息发送到名为debug.log的文件,请使用:

 $ ./your-program.py --logging-level=debug --logging-file=debug.log 

可以打印什么Python行被执行 (谢谢Geo!)。 这有许多的应用程序,例如,你可以修改它来检查什么时候调用特定的函数,或者添加一些像##使它只跟踪特定的行。

code.interact带你进入一个交互式的控制台

 import code; code.interact(local=locals()) 

如果你想能够轻松地访问你的控制台历史,请看:“ 我可以有一个像在shell中的历史机制? ”(将不得不低头看待它)。

可以为解释器启用自动完成。

ipdb就像pdb,具有ipython的可怕性。

print报表

  • 有些人推荐使用debug_print函数,而不是打印,以方便禁用
  • pprint模块对于复杂的结构是非常有用的

debugging脚本的明显方法

 python -m pdb script.py 
  • 当脚本引发exception时很有用
  • 在使用virtualenv和pdb命令时不用venvs python版本运行。

如果你不知道脚本在哪里

 python -m pdb ``which <python-script-name>`` 

PyDev的

PyDev有一个相当不错的交互式debugging器。 它具有监视expression式,hover评估,线程和堆栈列表以及(几乎)所有常用的设施,您可以从现代的可视化debugging器中获得期望。 您甚至可以连接到正在运行的进程并进行远程debugging。

像其他的可视化debugging器一样,我发现它主要用于简单的问题,或者在我尝试了其他所有的东西之后发现非常复杂的问题。 我仍然用伐木做大部分工作。

如果您熟悉Visual Studio,则Visual Studio的Python工具就是您所需要的。

在这里输入图像描述

Winpdb非常好,与它的名字相反,它完全是跨平台的。

它有一个非常好的基于提示的GUIdebugging器,并支持远程debugging。

在Vim中,我有这三个绑定:

 map <F9> Oimport rpdb2; rpdb2.start_embedded_debugger("asdf") #BREAK<esc> map <F8> Ofrom nose.tools import set_trace; set_trace() #BREAK<esc> map <F7> Oimport traceback, sys; traceback.print_exception(*sys.exc_info()) #TRACEBACK<esc> 

rpdb2是一个远程Pythondebugging器,可以与WinPDB(一个可靠的graphicsdebugging器)一起使用。 因为我知道你会问,它可以做我希望graphicsdebugging器做的一切:)

我从nose.tools使用pdb ,以便我可以debuggingunit testing以及正常的代码。

最后, F7映射会打印出一个回溯(类似于在栈顶出现exception时的types)。 我发现它真的有用超过几次。

为你的类定义有用的repr ()方法(所以你可以看到一个对象是什么)和使用repr()或者“%r”%(…)或者“… {0!r} ..” (…)在您的debugging消息/日志是恕我直言高效debugging的关键。

此外,其他答案中提到的debugging器将使用repr ()方法。

从正在运行的Python应用程序获取堆栈跟踪

这里有几个技巧。 这些包括

  • 打破解释器/发送信号打印堆栈跟踪
  • 从无准备的Python进程中获取堆栈跟踪
  • 用标志运行解释器,使其对debugging有用

如果你不喜欢在debugging器中花费时间(并且不理解pdb命令行界面的可用性差),那么可以转储执行跟踪并稍后分析它。 例如:

 python -m trace -t setup.py install > execution.log 

这会将setup.py install执行的所有源代码行转储到execution.log

为了更容易定制跟踪输出并编写自己的跟踪器,我将一些代码放到xtrace模块(公共领域)中。

在可能的情况下,我使用emacs中的Mx pdb进行debugging以进行源代码级别的debugging。

Udacity的Andreas Zeller提供了一个名为“ 软件debugging ”的完整在线课程,其中包含关于debugging的技巧:

课程总结

在本课中,您将学习如何系统地debugging程序,如何自动执行debugging过程以及如何在Python中构build多个自动debugging工具。

为什么select这门课程?

在本课程结束时,您将对系统debugging有深入的了解,知道如何自动化debugging,并将在Python中构build多个functiondebugging工具。

先决条件和要求

对于Udacity CS101或更高级别的编程和Python的基本知识是必需的。 对面向对象编程的基本理解是有帮助的。

强烈推荐。

如果你想以一种可读的方式打印你的调用堆栈的一个很好的graphics方式,看看这个工具: https : //github.com/joerick/pyinstrument

从命令行运行:

 python -m pyinstrument myscript.py [args...] 

作为模块运行:

 from pyinstrument import Profiler profiler = Profiler() profiler.start() # code you want to profile profiler.stop() print(profiler.output_text(unicode=True, color=True)) 

用django运行:

只需将pyinstrument.middleware.ProfilerMiddleware添加到MIDDLEWARE_CLASSES ,然后将?profile添加到请求URL的末尾以激活分析器。