使用IPython分步调试 [英] Step-by-step debugging with IPython

查看:156
本文介绍了使用IPython分步调试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从我所看到的,有两种方式来调试Python中的代码:

From what I have read, there are two ways to debug code in Python:


  • 使用传统的调试器,如 pdb ipdb 。这支持 c 的命令,例如 continue n step-over s for step-into 等),但是您不能直接访问IPython外壳,这对于对象检查非常有用。

  • With a traditional debugger such as pdb or ipdb. This supports commands such as c for continue, n for step-over, s for step-into etc.), but you don't have direct access to an IPython shell which can be extremely useful for object inspection.

使用 IPython 通过嵌入代码中的IPython shell。您可以从ipython import embed 中执行,然后在代码中使用 embed()。当您的程序/脚本命中 embed()语句时,您将被丢弃到IPython shell中。这允许使用所有IPython的好东西全面检查对象和测试Python代码。但是,使用 embed()时,您无法通过代码再次使用方便的键盘快捷键

Using IPython by embedding an IPython shell in your code. You can do from ipython import embed, and then use embed() in your code. When your program/script hits an embed() statement, you are dropped into an IPython shell. This allows the full inspection of objects and testing of Python code using all the IPython goodies. However, when using embed() you can't step-by-step through the code anymore with handy keyboard shortcuts.

有没有办法结合两个世界最好的?即可以使用方便的pdb / ipdb键盘快捷键,通过代码逐步

Is there any way to combine the best of both worlds? I.e.

    / li>
  1. 在任何这样的步骤(例如给定的语句)上,都可以访问一个完整的 IPython shell

  1. Be able to step-by-step through your code with handy pdb/ipdb keyboard shortcuts.
  2. At any such step (e.g. on a given statement), have access to a full-fledged IPython shell.



IPython调试 MATLAB:



这种类型的增强型调试可以在MATLAB中找到,其中用户始终可以完全访问MATLAB引擎/ shell,她仍然可以通过她的代码逐步定义条件断点等等。从与其他用户讨论的内容,这是从MATLAB转移到IPython时人们最想错过的调试功能。

IPython debugging as in MATLAB:

An example of this type of "enhanced debugging" can be found in MATLAB, where the user always has full access to the MATLAB engine/shell, and she can still step-by-step through her code, define conditional breakpoints, etc. From what I have discussed with other users, this is the debugging feature that people miss the most when moving from MATLAB to IPython.

我不想让问题太具体,但是我主要在Emacs中工作,所以我想知道是否有任何方法将此功能带入。 理想,Emacs(或编辑器)将允许程序员在代码的任何位置设置断点,并与解释器或调试器进行通信,使其停留在您选择的位置,并带来完整的IPython

I don't want to make the question too specific, but I work mostly in Emacs, so I wonder if there is any way to bring this functionality into it. Ideally, Emacs (or the editor) would allow the programmer to set breakpoints anywhere on the code and communicate with the interpreter or debugger to have it stop in the location of your choice, and bring to a full IPython interpreter on that location.

推荐答案

(2016年5月28日更新)在Emacs中使用RealGUD



对于Emacs中的任何人,此主题显示如何在Emacs中,使用

(Update on May 28, 2016) Using RealGUD in Emacs

For anyone in Emacs, this thread shows how to accomplish everything described in the OP (and more) using


  1. 一个新的重要调试器,可以实现OP(和更多)中所述的所有内容,这些调试器可以被称为 RealGUD 使用任何调试器(包括 ipdb )。

  2. Emacs包 isend-mode

  1. a new important debugger in Emacs called RealGUD which can operate with any debugger (including ipdb).
  2. The Emacs package isend-mode.

这两个软件包的组合是非常强大的,可以让您完全重新创建OP中描述的行为,甚至可以更多。

The combination of these two packages is extremely powerful and allows one to recreate exactly the behavior described in the OP and do even more.

更多信息RealGUD for ipdb的wiki文章的一个href =https://github.com/rocky/emacs-dbgr/wiki/ipdb-notes =noreferrer

More info on the wiki article of RealGUD for ipdb.

在尝试了许多不同的Python调试方法后,这个线程是我使用IPython调试Python的首选方法之一是嵌入式shell。

After having tried many different methods for debugging Python, including everything mentioned in this thread, one of my preferred ways of debugging Python with IPython is with embedded shells.

将脚本中的以下内容添加到 PYTHONPATH ,以便方法 ipsh()可用。

Add the following on a script to your PYTHONPATH, so that the method ipsh() becomes available.

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

Then, whenever I want to debug something in my code, I place ipsh() right at the location where I need to do object inspection, etc. For example, say I want to debug my_function below

def my_function(b):
  a = b
  ipsh() # <- This will embed a full-fledged IPython interpreter
  a = 4

然后我调用 my_function(2 )以下方式之一:

and then I invoke my_function(2) in one of the following ways:


  1. 通过运行从Unix调用此函数的Python程序shell

  2. 或直接从IPython调用它

无论我如何调用它,口译员在 ipsh()的行停止。完成后,您可以执行 Ctrl-D ,Python将恢复执行(使用您所做的任何可变更新)。请注意,如果您从常规IPython(IPython shell)(上述情况2)运行代码,新的IPython shell将在您调用该IPython外壳的嵌套之前完成,这是非常好的,但是这是很好的意识到。无论如何,一旦解释器停在 ipsh 的位置,我可以检查 a (的值为$

Regardless of how I invoke it, the interpreter stops at the line that says ipsh(). Once you are done, you can do Ctrl-D and Python will resume execution (with any variable updates that you made). Note that, if you run the code from a regular IPython the IPython shell (case 2 above), the new IPython shell will be nested inside the one from which you invoked it, which is perfectly fine, but it's good to be aware of. Eitherway, once the interpreter stops on the location of ipsh, I can inspect the value of a (which be 2), see what functions and objects are defined, etc.

上面的解决方案可以让Python在您的代码中停止任何位置,然后将其放入完全成熟的IPython解释器中。不幸的是,一旦你调用脚本,这是非常令人沮丧的,它不允许你添加或删除断点。在我看来,这是防止IPython成为Python的一个很好的调试工具的唯一的

The solution above can be used to have Python stop anywhere you want in your code, and then drop you into a fully-fledged IPython interpreter. Unfortunately it does not let you add or remove breakpoints once you invoke the script, which is highly frustrating. In my opinion, this is the only thing that is preventing IPython from becoming a great debugging tool for Python.

解决方法是放置 ipsh ()先于您希望Python解释器启动IPython shell的不同位置(即断点)。然后,您可以使用 Ctrl-D 在不同的预定义,硬编码的断点之间跳转,这将退出当前嵌入的IPython shell,每当解释器停止点击下一次调用 ipsh()

A workaround is to place ipsh() a priori at the different locations where you want the Python interpreter to launch an IPython shell (i.e. a breakpoint). You can then "jump" between different pre-defined, hard-coded "breakpoints" with Ctrl-D, which would exit the current embedded IPython shell and stop again whenever the interpreter hits the next call to ipsh().

如果你走这条路线,一种退出调试模式并忽略所有后续断点的方法是使用 ipshell.dummy_mode = True 这将使Python忽略我们上面创建的 ipshell 对象的任何后续实例。

If you go this route, one way to exit "debugging mode" and ignore all subsequent breakpoints, is to use ipshell.dummy_mode = True which will make Python ignore any subsequent instantiations of the ipshell object that we created above.

这篇关于使用IPython分步调试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆