一步一步与IPython的调试一步一步与IPython的调试(Step-by-step debugg

2019-05-12 12:19发布

从我已阅读,有两种方法可以在Python调试代码:

  • 与传统的调试器,如pdbipdb 。 这支持命令,如ccontinuen用于step-oversstep-into等),但不必到IPython的外壳,其可以是用于物体检查极其有用的直接访问。

  • 通过使用IPython的 嵌入代码中的一个IPython的壳。 你可以from ipython import embed ,然后用embed()在你的代码。 当你的程序/脚本击中embed()语句,你就进入一个IPython的外壳。 这允许使用所有的IPython的东西的Python代码和测试的全面检查。 然而,当使用embed()你无法通过代码一步一步再和方便的键盘快捷键。

有没有什么办法两全其美的结合? 即

  1. 能够通过与得心应手的pdb / IPDB键盘快捷键你的代码一步一步
  2. 在任何这样的步骤(例如,在给定的语句),有机会获得一个全面的IPython Shell。

IPython的调试 MATLAB:

这种类型的“增强的调试”的一个例子可以在MATLAB,用户总是可以完全访问Matlab引擎/壳发现,她仍然可以通过她的代码一步一步 ,定义条件断点等。从我已与其他用户讨论的,这是调试功能,人们正从MATLAB到IPython的时候最想念的。

IPython的调试在Emacs和其他编辑:

我不想让这个问题太具体,但我在Emacs大多是工作,所以我不知道是否有什么办法把这个功能集成到它。 理想情况下 ,Emacs的(或编辑器)将允许程序员在代码的任何地方设置断点,并解释或调试沟通,有它在您选择的位置停止,并提请在该位置的完整的IPython解释。

Answer 1:

没有人提到的IPython的%pdb标志呢。 只需拨打%pdb在IPython中,当出现错误时,你会自动下降到ipdb 。 虽然你不马上有步进,你是ipdb之后。

这使得调试各个功能简单,因为你只需要加载一个文件%load ,然后运行功能。 你可以强制错误与assert在正确的位置。



Answer 2:

什么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提示符工具 。



Answer 3:

(更新于2016 5月28日)在Emacs下使用RealGUD

对于在Emacs的人, 这个线程展示了如何实现在OP说明一切(及以上)使用

  1. 在Emacs一个新的重要的调试器称为RealGUD可与任何调试器(包括操作ipdb )。
  2. 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)中的以下列方式之一:

  1. 无论是通过运行在Unix外壳调用此功能的Python程序
  2. 或者直接从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 ,我们在上面创建的对象。



Answer 4:

您可以从启动IPython的会话pudb并返回到调试会话,只要你喜欢。

BTW,IPDB使用IPython的幕后,你可以实际使用IPython的功能,如TAB完成和魔法命令(与一个开始% )。 如果你是IPDB OK,你可以从IPython中使用以下命令启动%run%debug 。 IPDB会话是你可以去向上和向下的堆栈跟踪等什么是IPDB为“对象检查”失踪感比普通IPython的一个真正好?

此外,python.el捆绑使用Emacs> = 24.3具有良好的IPDB支持。



Answer 5:

看起来像@ gaborous的答案的做法已经过时 。

新的方法似乎是:

from IPython.core import debugger
debug = debugger.Pdb().set_trace

def buggy_method():
    debug()


Answer 6:

前缀一个“!” 符号您在PDB键入命令似乎有作为一个IPython的壳做一些同样的效果。 这适用于访问帮助某个功能,甚至变量名。 也许这将帮助你在一定程度上。 例如,

ipdb> help(numpy.transpose)
*** No help on (numpy.transpose)

但是!帮助(numpy.transpose)会给你numpy.transpose预期的帮助页面。 同样,对于变量名,说你在PDB列表中有一个变量l,输入“L”的代码,但镜!打印L值。



Answer 7:

你有没有尝试这个提示 ?

或者更好的是,使用IPython的,并呼吁:

 from IPython.Debugger import Tracer; debug_here = Tracer() 

那么你可以只使用

 debug_here() 

每当你想设置一个断点



Answer 8:

一种选择是使用像一个IDE 的Spyder应该让你在调试(使用IPython的控制台,实际上)与您的代码进行交互。 事实上,Spyder的非常MATLAB样,我推测是故意的。 这包括变量督察,变量编辑,内置的访问文档,等等。



Answer 9:

正确,容易,冷静,准确的问题,答案是使用%运行的宏与-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


Answer 10:

如果你键入嵌入的exit()()控制台代码继续进入下一个嵌入()线。



Answer 11:

该Pyzo IDE具有与OP问类似的功能。 你不必在调试模式下启动。 类似于MATLAB,所述命令在所述壳中执行。 当您设置的一些源代码行一个断点,IDE会停止执行那里,你可以调试和发布定期IPython的命令以及。

然而,这确实似乎逐步进入不(没?)很好地工作(也即停止在一个行,然后步入另一个函数),除非你成立另一个突破点。

不过,从MATLAB来,这似乎我已经找到了最好的解决方案。



Answer 12:

从Emacs的IPython的壳和断点通过pdb.set_trace设置内运行()应该工作。

经过使用python-mode.el,的Mx IPython中RET等。



Answer 13:

在Python 3.2,你有interact命令,它给你访问到完整的Python / IPython的命令空间。



文章来源: Step-by-step debugging with IPython