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可能看起来很熟悉。
很好的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的末尾以激活分析器。