Python调试技巧

Python debugging tips

调试Python的最佳技巧是什么?

请不要只是列出一个特定的调试器,而不说它实际上能做什么。

相关的

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


注塑级

您可以使用PDB模块,插入EDOCX1&3)任何地方,并将其作为一个突破点。

1
2
3
4
5
6
7
8
>>> import pdb
>>> a="a string"
>>> pdb.set_trace()
--Return--
> <stdin>(1)<module>()->None
(Pdb) p a
'a string'
(Pdb)

继续使用ccontcontinue

可以用PDB执行任意Python表达式。例如,如果你发现错误,你可以更正代码,然后类型的表达在运行代码中具有相同的效果。

ipdb是ipython的PDB版本。它使PDB的使用与所有ipython特性包括Tab完成。

这也有可能使PDB在一个不确定的例外情况下自动运行。

PYDB被写成了增强PDB版本。福利?


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

Its goal is to provide all the niceties of modern GUI-based debuggers in a more lightweight and keyboard-friendly package. PuDB allows you to debug code right where you write and test it – in a terminal. If you've worked with the excellent (but nowadays ancient) DOS-based Turbo Pascal or C tools, PuDB's UI might look familiar.

pudb screenshot

很适合调试独立脚本,只需运行

1
python -m pudb.run my-script.py


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 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


测井

Python在测井模块中有一个很好的建筑物。你可能想在这里使用这个标志。

测井模块说明了一个重要的程度;在解析过程中,你可以记录所有的东西,而在正常操作过程中,你可能只记录一些重要的东西。你可以随意开关东西。

大多数人只是使用基本印刷声明来进行讨论,然后再提出印刷声明。你最好把他们留在里面,但不能把他们留在里面;然后,当你有另一个错误,你可以重新开始所有的东西,看看你的房间。

这可以是一种最佳的方法,以快速启动需要的程序,例如网络程序,在网络连接的其他终端出现和离开之前需要响应这些程序。你可能没有多少时间单步走一步,但你可以让你的代码运行,并记录所有的事情,然后把它打开,然后把它变成事实。

编辑:The original URL for the Templates was:http://aymanh.com/python-debugging-techniques

This page is missing so I replaced it with a reference to the snapshot saved at archive.org:http://web.archive.org/web/20120819135307/http://aymanh.com/python-debugging-techniques

在这一点上,我再次指出了。这是从博客中提取的代码,我没有写。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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()

这是他对如何使用它的解释。再说一次,我没有得到这个信用:

通过Default,测井模块印刷关键、误差和预警信息。To change this so that all levels are printed,use:

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

To send log messages to a file called debug.log,use:

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


有可能打印Python线条被执行(谢谢GEO!)This has any number of applications,for example,you could modify it to check when particular functions are called or add something like 350; 355;make it only track particular lines.

互动式控制台

ZZU1

如果你想方便地进入你的控制台历史看着"我能有一个类似于壳牌的历史机制吗?"(Will have to look down for it).

自行完成可供翻译使用。


ipdb就像pdb,with the awesomens of ipython.


printStatements

  • 一些人推荐一个EDOCX1&1)功能Instead of print for easy disabling
  • 模块对于复杂结构是无效的。


调试脚本的明显方法

1
python -m pdb script.py
  • 当脚本引发异常时很有用
  • 在使用virtualenv和pdb命令时很有用,该命令不与venvs python版本一起运行。

如果你不知道脚本在哪里

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

如果您熟悉Visual Studio,那么您需要的是用于Visual Studio的Python工具。

enter image description here


皮德夫

Pydev有一个很好的交互解调器。它有表达式,点火到评价,线程和堆栈列表,以及(至少)所有你通常期望的现代视觉解调。你甚至可以加入一个运行过程并进行远程解调。

就像其他的视觉解体者一样,尽管如此,我发现它主要用于简单的问题,或是在我尝试了所有事情之后,非常复杂的问题。我仍然在用测井机升降。


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

它有一个非常好的基于提示和GUI的调试器,并且支持远程调试。


在Vim中,我有三个绑定:

1
2
3
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是一个远程python调试器,它可以与一个坚实的图形调试器winpdb一起使用。因为我知道你会问,它可以做我希望图形调试器做的所有事情:)

我使用nose.tools中的pdb,以便调试单元测试和正常代码。

最后,F7映射将打印一个回溯(类似于异常冒泡到堆栈顶部时得到的类型)。我发现它确实有用很多次。


为类定义有用的repr()方法(以便您可以看到对象是什么),并使用repr()或"%r"%(…)或"…0!"调试消息/日志中的r…".format(…)是有效调试的关键。

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


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

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

  • 通过发送信号闯入解释器/打印堆栈跟踪
  • 从未准备好的python进程中获取堆栈跟踪
  • 运行带有标志的解释器以使其对调试有用

如果您不喜欢在调试程序中花费时间(并且不喜欢pdb命令行界面的低可用性),您可以转储执行跟踪并稍后对其进行分析。例如:

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

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

为了使定制跟踪输出和编写自己的跟踪程序更容易,我将一些代码放在Xtrace模块(公共域)中。


如有可能,我会用M-x pdb在电子邮件中进行源级解调。


在Udacity上有一个名为"软件调试"的完整在线课程,里面有关于调试的提示:

Course Summary

In this class you will learn how to debug programs systematically, how
to automate the debugging process and build several automated
debugging tools in Python.

Why Take This Course?

At the end of this course you will have a solid understanding about
systematic debugging, will know how to automate debugging and will
have built several functional debugging tools in Python.

Prerequisites and Requirements

Basic knowledge of programming and Python at the level of Udacity
CS101 or better is required. Basic understanding of Object-oriented
programming is helpful.

强烈推荐。


如果您想要以一种可读的方式打印您的调用堆栈,请查看该实用程序:https://github.com/joerick/pyinstrument

从命令行运行:

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

作为模块运行:

1
2
3
4
5
6
7
8
9
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的末尾即可激活探查器。