从我已阅读,有两种方法可以在Python调试代码:
与传统的调试器,如pdb
或ipdb
。 这支持命令,如c
为continue
, n
用于step-over
, s
为step-into
等),但不必到IPython的外壳,其可以是用于物体检查极其有用的直接访问。
通过使用IPython的 嵌入代码中的一个IPython的壳。 你可以from ipython import embed
,然后用embed()
在你的代码。 当你的程序/脚本击中embed()
语句,你就进入一个IPython的外壳。 这允许使用所有的IPython的东西的Python代码和测试的全面检查。 然而,当使用embed()
你无法通过代码一步一步再和方便的键盘快捷键。
有没有什么办法两全其美的结合? 即
- 能够通过与得心应手的pdb / IPDB键盘快捷键你的代码一步一步 。
- 在任何这样的步骤(例如,在给定的语句),有机会获得一个全面的IPython Shell。
IPython的调试在 MATLAB:
这种类型的“增强的调试”的一个例子可以在MATLAB,用户总是可以完全访问Matlab引擎/壳发现,她仍然可以通过她的代码一步一步 ,定义条件断点等。从我已与其他用户讨论的,这是调试功能,人们正从MATLAB到IPython的时候最想念的。
IPython的调试在Emacs和其他编辑:
我不想让这个问题太具体,但我在Emacs大多是工作,所以我不知道是否有什么办法把这个功能集成到它。 理想情况下 ,Emacs的(或编辑器)将允许程序员在代码的任何地方设置断点,并解释或调试沟通,有它在您选择的位置停止,并提请在该位置的完整的IPython解释。
没有人提到的IPython的%pdb
标志呢。 只需拨打%pdb
在IPython中,当出现错误时,你会自动下降到ipdb
。 虽然你不马上有步进,你是ipdb
之后。
这使得调试各个功能简单,因为你只需要加载一个文件%load
,然后运行功能。 你可以强制错误与assert
在正确的位置。
什么ipdb.set_trace()? 在您的代码:
import ipdb; ipdb.set_trace()
更新 :现在在Python 3.7,我们可以写breakpoint()
它的工作原理是相同的,但它也服从于PYTHONBREAKPOINT
环境变量。 此功能来自这个PEP 。
这允许你的代码进行全面检查,并可以访问如命令c
(继续), n
(执行下一行), s
(步入以点的方法)等。
见IPDB回购和命令的列表 。 IPython的现在被称为:(编辑部分) Jupyter 。
PS:注意,IPDB命令优先于Python代码。 因此,为了写list(foo)
你需要print list(foo)
。
另外,如果你喜欢IPython的提示(其Emacs和Vim模式,历史,完井,...)很容易,因为它的基础上,以获得相同的为你的项目Python提示符工具 。
(更新于2016 5月28日)在Emacs下使用RealGUD
对于在Emacs的人, 这个线程展示了如何实现在OP说明一切(及以上)使用
- 在Emacs一个新的重要的调试器称为RealGUD可与任何调试器(包括操作
ipdb
)。 - emacs包
isend-mode
。
这两个包的组合是非常强大的,允许一个准确地重建在OP描述的行为和做更多。
关于更多信息维基文章 RealGUD为IPDB。
原来的答案:
有用于调试的Python,包括在这个线程中提到的一切尝试了许多不同的方法后,我的首选用IPython中调试的Python的方法之一就是嵌入式弹。
定义一个定制的嵌入式IPython的外壳:
在脚本里添加到您的PYTHONPATH
,因此该方法ipsh()
变为可用。
import inspect
# First import the embed function
from IPython.terminal.embed import InteractiveShellEmbed
from IPython.config.loader import Config
# Configure the prompt so that I know I am in a nested (embedded) shell
cfg = Config()
prompt_config = cfg.PromptManager
prompt_config.in_template = 'N.In <\\#>: '
prompt_config.in2_template = ' .\\D.: '
prompt_config.out_template = 'N.Out<\\#>: '
# Messages displayed when I drop into and exit the shell.
banner_msg = ("\n**Nested Interpreter:\n"
"Hit Ctrl-D to exit interpreter and continue program.\n"
"Note that if you use %kill_embedded, you can fully deactivate\n"
"This embedded instance so it will never turn on again")
exit_msg = '**Leaving Nested interpreter'
# Wrap it in a function that gives me more context:
def ipsh():
ipshell = InteractiveShellEmbed(config=cfg, banner1=banner_msg, exit_msg=exit_msg)
frame = inspect.currentframe().f_back
msg = 'Stopped at {0.f_code.co_filename} at line {0.f_lineno}'.format(frame)
# Go back one level!
# This is needed because the call to ipshell is inside the function ipsh()
ipshell(msg,stack_depth=2)
于是,每当我想在我的代码调试的东西,我把ipsh()
就在那里我需要做的对象检查等。例如位置,说我要调试my_function
以下
使用它:
def my_function(b):
a = b
ipsh() # <- This will embed a full-fledged IPython interpreter
a = 4
然后我调用my_function(2)
中的以下列方式之一:
- 无论是通过运行在Unix外壳调用此功能的Python程序
- 或者直接从IPython的调用它
不管我怎么调用它,解释停在这行ipsh()
一旦你完成,你可以做到Ctrl-D
和Python将恢复执行(与之前所做的任何变量更新)。 需要注意的是,如果您从一个普通的IPython IPython的外壳(上述情况2),新的IPython Shell的代码将嵌套从中调用它的人,这是完全正常的内部,但它是很好的了解。 Eitherway,一旦解释器上的位置停止ipsh
,我可以检查的值a
(其为2
),见定义了什么功能和物体等
问题:
以上解决方案可用于安装Python你想要的任何地方停在你的代码,然后放弃你到一个完全成熟的IPython解释。 不幸的是它不会让你添加或删除断点,一旦你调用脚本,这是非常令人沮丧的。 在我看来,这是防止IPython都成为Python的一个伟大的调试工具的唯一的事情。
你可以现在做的最好的:
一种解决方法是将ipsh()
先验在您想要Python解释器启动一个IPython的壳(即不同位置breakpoint
)。 然后,您可以“跳”不同的预定义的,硬编码的“断点”与之间Ctrl-D
这将退出当前嵌入式IPython的外壳,并再次停止每当解释打一次调用ipsh()
如果你走这条路线,单程退出“调试模式”,而忽略所有后续断点,是使用ipshell.dummy_mode = True
,这将使Python忽略的任何后续实例ipshell
,我们在上面创建的对象。
您可以从启动IPython的会话pudb并返回到调试会话,只要你喜欢。
BTW,IPDB使用IPython的幕后,你可以实际使用IPython的功能,如TAB完成和魔法命令(与一个开始%
)。 如果你是IPDB OK,你可以从IPython中使用以下命令启动%run
和%debug
。 IPDB会话是你可以去向上和向下的堆栈跟踪等什么是IPDB为“对象检查”失踪感比普通IPython的一个真正好?
此外,python.el捆绑使用Emacs> = 24.3具有良好的IPDB支持。
看起来像@ gaborous的答案的做法已经过时 。
新的方法似乎是:
from IPython.core import debugger
debug = debugger.Pdb().set_trace
def buggy_method():
debug()
前缀一个“!” 符号您在PDB键入命令似乎有作为一个IPython的壳做一些同样的效果。 这适用于访问帮助某个功能,甚至变量名。 也许这将帮助你在一定程度上。 例如,
ipdb> help(numpy.transpose)
*** No help on (numpy.transpose)
但是!帮助(numpy.transpose)会给你numpy.transpose预期的帮助页面。 同样,对于变量名,说你在PDB列表中有一个变量l,输入“L”的代码,但镜!打印L值。
你有没有尝试这个提示 ?
或者更好的是,使用IPython的,并呼吁:
from IPython.Debugger import Tracer; debug_here = Tracer()
那么你可以只使用
debug_here()
每当你想设置一个断点
一种选择是使用像一个IDE 的Spyder应该让你在调试(使用IPython的控制台,实际上)与您的代码进行交互。 事实上,Spyder的非常MATLAB样,我推测是故意的。 这包括变量督察,变量编辑,内置的访问文档,等等。
正确,容易,冷静,准确的问题,答案是使用%运行的宏与-d标志。
In [4]: run -d myscript.py
NOTE: Enter 'c' at the ipdb> prompt to continue execution.
> /cygdrive/c/Users/mycodefolder/myscript.py(4)<module>()
2
3
----> 4 a=1
5 b=2
如果你键入嵌入的exit()()控制台代码继续进入下一个嵌入()线。
该Pyzo IDE具有与OP问类似的功能。 你不必在调试模式下启动。 类似于MATLAB,所述命令在所述壳中执行。 当您设置的一些源代码行一个断点,IDE会停止执行那里,你可以调试和发布定期IPython的命令以及。
然而,这确实似乎逐步进入不(没?)很好地工作(也即停止在一个行,然后步入另一个函数),除非你成立另一个突破点。
不过,从MATLAB来,这似乎我已经找到了最好的解决方案。
从Emacs的IPython的壳和断点通过pdb.set_trace设置内运行()应该工作。
经过使用python-mode.el,的Mx IPython中RET等。
在Python 3.2,你有interact
命令,它给你访问到完整的Python / IPython的命令空间。