Python调试技巧[关闭]

     2023-02-19     51

关键词:

【中文标题】Python调试技巧[关闭]【英文标题】:Python debugging tips [closed] 【发布时间】:2010-12-10 00:45:07 【问题描述】:

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

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

相关

What are good ways to make my Python code run first time? - 讨论最小化错误

【问题讨论】:

gist.github.com/rduplain/4983839 【参考方案1】:

PDB

您可以使用 pdb 模块,在任何地方插入pdb.set_trace(),它将充当断点。

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

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

可以使用 pdb 执行任意 Python 表达式。例如,如果发现错误,可以更正代码,然后键入类型表达式以在运行代码中产生相同的效果

ipdb 是 IPython 的 pdb 版本。它允许将 pdb 与所有 IPython 功能一起使用,包括制表符补全。

也可以在未捕获的异常上set pdb to automatically run。

Pydb 被编写为 Pdb 的增强版本。好处?

【讨论】:

这里有一篇关于使用pdb的文章:sontek.net/debugging-python-with-pdb 就个人而言,我更喜欢ipdb。 显然有一个名为pydbgr的pydb重写 SublimeText 有一个很棒的插件可以在代码中添加 python 断点:sublime.wbond.net/packages/Python%20Breakpoints 如果您正在开发 Web 应用程序,请在调试模式下为 myserver.com/pdb 添加一个视图,该视图仅执行 import pdb; pdb.set_trace()。如果您使用的是具有交互式调试器的 Flask/Werkzeug,您还可以拥有一个只执行 assert False 的视图。【参考方案2】:

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

它的目标是在一个更轻量级和键盘友好的包中提供现代基于 GUI 的调试器的所有细节。 PuDB 允许您在终端中在您编写和测试代码的地方调试代码。如果您使用过基于 DOS 的优秀(但现在很古老)的 Turbo Pascal 或 C 工具,PuDB 的 UI 可能看起来很熟悉。

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

python -m pudb.run my-script.py

【讨论】:

使用pip install pudb安装【参考方案3】:

如果您使用 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

【讨论】:

你如何定义这些别名? 把这些东西放到~/.pdbrc 在windows上你可以把它放在~/_ipython/ipythonrc.ini【参考方案4】:

记录

Python 已经拥有出色的 built-in logging module。您可能想使用logging template here。

日志记录模块让您指定重要程度;在调试期间,您可以记录所有内容,而在正常操作期间,您可能只记录关键内容。您可以关闭和打开设备。

大多数人只是使用基本的打印语句进行调试,然后删除打印语句。最好将它们留在里面,但禁用它们;然后,当您遇到另一个错误时,您可以重新启用所有内容并查看您的日志。

这可能是调试需要快速执行操作的程序的最佳方法,例如需要在网络连接的另一端超时并消失之前做出响应的网络程序。您可能没有太多时间单步调试器;但是你可以让你的代码运行,并记录所有内容,然后仔细研究日志并找出真正发生的事情。

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

此页面已丢失,因此我将其替换为对保存在 archive.org 的快照的引用: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

【讨论】:

日志模块的问题在于它严重破坏了 Unicode,需要各种变通方法才能使其在国际化应用程序中工作。尽管如此,这仍然是 Python 的最佳日志记录解决方案。 链接“此处的日志记录模板”已失效。请更新。【参考方案5】:

可以打印Python lines are executed 的内容(感谢 Geo!)。这有任意数量的应用程序,例如,您可以对其进行修改以检查何时调用特定函数或添加类似 ## 之类的内容,使其仅跟踪特定行。

code.interact 带您进入交互式控制台

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

如果您希望能够轻松访问控制台历史记录,请查看:“Can I have a history mechanism like in the shell?”(必须向下查找)。

可以为interpreter 启用自动完成功能。

【讨论】:

【参考方案6】:

ipdb 就像 pdb,具有 ipython 的厉害之处。

【讨论】:

你能补充更多关于它可以做什么的细节吗?【参考方案7】:

print 声明

有些人建议使用 debug_print 函数而不是 print 以便于禁用 pprint 模块对于复杂结构非常有用

【讨论】:

+1 当每个调试器都失败时,print 是你的朋友,是的 debug_print 会是很好的补充 我通常先打印然后再调试,除非我知道我将能够通过跟踪特定部分来解决 其实日志模块就是这么做的。 是的,但必须设置日志记录。荣誉之后我会学习如何使用模块 print 对于简单的情况很有用,尤其是在开发启动时间较短的项目时。另一方面,它可能会让人上瘾,在更复杂的场景中通过 pdb 或任何其他调试器使用它通常会让你头疼【参考方案8】:

调试脚本的明显方法

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

如果您不知道该脚本的确切位置

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

【讨论】:

【参考方案9】:

PyDev

PyDev 有一个非常好的交互式调试器。它具有监视表达式、悬停评估、线程和堆栈列表以及(几乎)您期望从现代可视化调试器获得的所有常用功能。您甚至可以附加到正在运行的进程并进行远程调试。

不过,与其他可视化调试器一样,我发现它主要用于解决简单问题,或者在我尝试了所有其他方法后非常复杂的问题。我仍然负责大部分繁重的日志记录工作。

【讨论】:

它有编辑和继续的能力吗? @CaseBash 不,它没有,但该功能已计划。即使没有它,设置/取消设置断点和查看变量值的速度和易用性仍然非常有用【参考方案10】:

如果您熟悉 Visual Studio,Python Tools for Visual Studio 就是您要找的。​​p>

【讨论】:

【参考方案11】:

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

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

【讨论】:

@Casebash - 添加了更多细节 +1 这是迄今为止我发现的唯一可以处理多线程的python调试器。 小心它对多线程的“处理”——任何线程中的任何异常都会导致整个进程冻结。如果你意识到它不是一件坏事,如果你不知道它会很痛苦 该项目在 2014 年 4 月看起来已经死了【参考方案12】:

在 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 是一个远程 Python 调试器,可以与 WinPDB 一起使用,这是一个可靠的图形调试器。因为我知道你会问,它可以做我期望图形调试器做的所有事情:)

我使用nose.tools 中的pdb,这样我就可以调试单元测试以及普通代码。

最后,F7 映射将打印回溯(类似于当异常冒泡到堆栈顶部时得到的那种)。我发现它真的很有用不止几次。

【讨论】:

【参考方案13】:

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

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

【讨论】:

【参考方案14】:

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

有几个技巧here。其中包括

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

【讨论】:

【参考方案15】:

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

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

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

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

【讨论】:

【参考方案16】:

如果可能,我会在 emacs 中使用 M-x pdb 进行源代码级调试。

【讨论】:

【参考方案17】:

Andreas Zeller 在 Udacity 上有一个名为“Software Debugging”的完整在线课程,其中包含有关调试的提示:

课程总结

在本课程中,您将学习如何系统地调试程序,如何 自动化调试过程并构建几个自动化的 Python 中的调试工具。

为什么要学习这门课程?

在本课程结束时,您将深入了解 系统调试,会知道如何自动化调试,并且会 已经用 Python 构建了几个功能调试工具。

先决条件和要求

Udacity 级别的编程和 Python 基础知识 需要 CS101 或更高版本。面向对象的基本理解 编程很有帮助。

强烈推荐。

【讨论】:

【参考方案18】:

如果您想要一种漂亮的图形方式以可读的方式打印调用堆栈,请查看此实用程序: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 的末尾即可激活分析器。

【讨论】:

javascript调试技巧

1.‘debugger;’除了console.log,debugger;是我们最喜欢、快速且肮脏的调试工具。一旦执行到这行代码,Chrome会在执行时自动停止。你甚至可以使用条件语句加上判断,这样可以只在你需要的时候运行。愚人码头注:本人实在觉得这种... 查看详情

chrome调试折腾记_js断点调试技巧

JS调试技巧技巧一:格式化压缩代码技巧二:快速跳转到某个断点的位置右侧的Breakpoints会汇总你在JS文件所有打过的断点,点击跟checkbox同一行的会暂时取消这个断点,若是点击checkbox下一行的会直接跳转到该断点的位置技巧三... 查看详情

javascript调试技巧

1.打印输出信息console.log用于通常的打印信息console.table打印对象信息;console.trace(‘tracecar’)查看函数的调用栈,特别地有效。3.断点调试有三个方法,一、直接找出代码行加个断点;二、在代码中添加debugger,浏览器会自动在debu... 查看详情

flash漏洞调试技巧

本周中心抓到一个在野的flash0day(相关信息见此链接),于是又捡起了一年多的flash漏洞的相关知识,遂总结一下。普通的trace调试flasher样本一般建议使用调试版的flashplayer,在调试版本下可以输出swf文件运行时的相关日志,便... 查看详情

你最喜欢的 Windbg 提示/技巧是啥? [关闭]

...描述】:我开始意识到Windbg是一个非常强大的Windows平台调试器,我偶尔会学到一些关于它的新东西。其他Windbg用户可以分享他们的一些疯狂技能吗?ps:我不是在寻找一个漂亮的命令 查看详情

visualstudio2015中的常用调试技巧分享

.NET技术交流群:337901356欢迎您的加入!为什么要学习调试?  调试(Debug)是作为一个程序员必须要学会的东西,学会调试可以极大的提高开发效率,排错时间,很多人不喜欢调试,但我认为这是一个很不可取的选择,调试... 查看详情

调试/分析python扩展[关闭]

】调试/分析python扩展[关闭]【英文标题】:Debugging/profilingpythonextensions[closed]【发布时间】:2012-07-1719:01:27【问题描述】:我使用出色的f2py工具将我的大部分代码编写为Python的Fortran扩展。然而,有时很难捕捉到内存泄漏,并分析... 查看详情

js调试必备的5个debug技巧

1.debugger; debugger语句用于停止执行JavaScript,并调用(如果可用)调试函数。使用debugger语句类似于在代码中设置断点。通常,你可以通过按下F12开启调试工具,并在调试菜单中选择"Console"。进入断点后,可以双击下面的某行代码,... 查看详情

lua-调试技巧(代码片段)

title:lua-调试技巧categories:Luatags:[lua,调试,技巧]date:2022-07-1416:31:27comments:falsemathjax:truetoc:truelua-调试技巧前篇游戏lua脚本调试技巧,达到修改逻辑脚本后能实时生效执行,提高开发效率pc端editor模式新建一个测试代码脚本gDebugCustom=gD... 查看详情

lua-调试技巧(代码片段)

title:lua-调试技巧categories:Luatags:[lua,调试,技巧]date:2022-07-1416:31:27comments:falsemathjax:truetoc:truelua-调试技巧前篇游戏lua脚本调试技巧,达到修改逻辑脚本后能实时生效执行,提高开发效率pc端editor模式新建一个测试代码脚本gDebugCustom=gD... 查看详情

lua-调试技巧(代码片段)

title:lua-调试技巧categories:Luatags:[lua,调试,技巧]date:2022-07-1416:31:27comments:falsemathjax:truetoc:truelua-调试技巧前篇游戏lua脚本调试技巧,达到修改逻辑脚本后能实时生效执行,提高开发效率pc端editor模式新建一个测试代码脚本gDebugCustom=gD... 查看详情

是否有调试cordova应用程序的真正解决方案[关闭]

】是否有调试cordova应用程序的真正解决方案[关闭]【英文标题】:Istherearealsolutiontodebugcordovaapps[closed]【发布时间】:2014-02-1510:59:18【问题描述】:过去两天我试图弄清楚如何调试我使用Cordova3.2创建并部署到Android2.3设备的HTML5应... 查看详情

调试.方便调试的技巧_01

1、例子代码:(VC6.0sp4)#include<stdio.h>#defineMAX(a,b)((a)>(b)?(a):(b))#defineM01()\__try{#defineM02()}__finally{#defineM03()}voidmain(){M01()inti=MAX(3,5);printf("AAA,i:%d ",i);return;printf(" 查看详情

继续分享5个实用的vs调试技巧(代码片段)

继续分享5个实用的vs调试技巧原总结调试vs2019vs前言我在上一篇文章《5个非常实用的vs调试技巧》中分享了5个我认为非常值得了解的vs调试技巧,本周继续分享5个很基础但同样实用的调试技巧。1.条件断点作用简介:顾名思义,... 查看详情

lua-调试技巧(代码片段)

title:lua-调试技巧categories:Luatags:[lua,调试,技巧]date:2022-07-1416:31:27comments:falsemathjax:truetoc:truelua-调试技巧前篇游戏lua脚本调试技巧,达到修改逻辑脚本后能实时生效执行,提高开发效率pc端editor模式新建一个测试代码脚本gDebugCustom=gD... 查看详情

什么是最佳的通用调试技巧?

】什么是最佳的通用调试技巧?【英文标题】:Whatarethebestgeneralpracticedebuggingtricks?【发布时间】:2011-05-2706:54:33【问题描述】:什么是最佳的常规调试技巧?不是与特定平台、语言等相关联的那些,而是那些你发现你使用的那些... 查看详情

javascript调试技巧(代码片段)

...ole.timeEnd()测试循环console.log()和console.dir()的区别阐述我们调试Javascript一般会用到Chrome和Firefox的控制台作为调试工具,本文列出了几条用于调试Javascript的技巧,掌握它们 查看详情

javascript调试技巧(代码片段)

...ole.timeEnd()测试循环console.log()和console.dir()的区别阐述我们调试Javascript一般会用到Chrome和Firefox的控制台作为调试工具,本文列出了几条用于调试Javascript的技巧,掌握它们 查看详情