断点诱导的Python与IPython交互调试

断点诱导的Python与IPython交互调试,python,debugging,breakpoints,ipython,Python,Debugging,Breakpoints,Ipython,假设我有一个IPython会话,我从中调用一些脚本: > run my_script.py 有没有一种方法可以在my_script.py中引入一个断点,从中我可以从IPython检查我的工作区 我记得在以前的IPython版本中,人们可以做到: from IPython.Debugger import Tracer; def my_function(): x = 5 Tracer() print 5; 但是子模块调试器似乎不再可用 假设我已经打开了一

假设我有一个IPython会话,我从中调用一些脚本:

> run my_script.py
有没有一种方法可以在
my_script.py
中引入一个断点,从中我可以从IPython检查我的工作区

我记得在以前的IPython版本中,人们可以做到:

from IPython.Debugger import Tracer;     

def my_function():
    x = 5
    Tracer()
    print 5;
但是子模块
调试器
似乎不再可用

假设我已经打开了一个IPython会话:如何在我选择的位置停止程序并使用IPython检查我的工作区


一般来说,我更喜欢不需要预先指定行号的解决方案,因为我希望可以对上面的
Tracer()
进行多个这样的调用,而不必跟踪行号所在的位置。

在IPython shell中,您可以这样做

from IPython.core.debugger import Pdb
pdb = Pdb()
pdb.runcall(my_function)

例如,或者在函数内部执行普通的
pdb.set_trace()

您可以运行它并在给定行设置断点,方法是:

run -d -b12 myscript

其中-b12在第12行设置断点。当您输入这一行时,您将立即进入pdb,并且您需要输入
c
以执行到该断点。

我一直有相同的问题,我发现的最好的解决方法是添加一行,该行将破坏我的代码,如下所示:

...
a = 1+2
STOP
...
然后,当我运行该代码时,它将中断,我可以执行%debug去那里检查。您还可以打开%pdb,使其始终指向代码中断的点,但如果您不想在每次代码中断时检查任何地方,这可能会很麻烦。我想要一个更优雅的解决方案。

Tracer()
仍然存在于ipython的另一个模块中。您可以执行以下操作:

from IPython.core.debugger import Tracer

def my_function():
    x = 5
    Tracer()()
    print 5
注意
Tracer

编辑:对于IPython 6以后的
跟踪器
,您应该使用
设置跟踪()

from IPython.core.debugger import set_trace

def my_function():
    x = 5
    set_trace()
    print 5

这是使用
set\u trace()
方法而不是不推荐的
Tracer()
方法的版本

from IPython.core.debugger import Pdb

def my_function():
    x = 5
    Pdb().set_trace()
    print 5
对于Python3(v3.7+),有一个新函数。您可以修改它的行为,以便它为您调用ipython的调试器

基本上,您可以将其指向调试器函数。(如果未设置变量,
breakpoint()
默认为调用pdb。)

要设置
breakpoint()
调用ipython的调试器,请将环境变量(在shell中)设置为:

#适用于bash/zsh用户
导出PYTHONBREAKPOINT='IPython.core.debugger.set\u trace'
#powershell用户
$env:PYTHONBREAKPOINT='IPython.core.debugger.set\u trace'
(注意,如果您想永久设置环境变量,显然需要修改shell配置文件或系统首选项。)

你可以写:

def my_函数():
x=5
断点()
印刷品5份;

它会为你进入ipython的调试器。我认为这比从IPython.core.debugger导入set_trace
并调用
set_trace()

更方便。出于好奇,为什么您一次需要多个跟踪程序?在这一点上,您似乎应该做日志记录,而不是调试。@Wilduck:我想在某些情况下检查我的工作区,这些情况可能发生在我的代码中的不同位置。好吧,也许我的问题措辞不当。我理解您为什么希望查看代码的不同部分。为什么要同时在代码中使用这些跟踪程序?如果您没有使用调试器永久修复一个bug(即一次修复一个bug),那么设置日志记录以自动收集有关程序在各种状态下运行的信息不是更好/更容易吗?我这么问是因为您似乎在尝试使用调试工具来完成日志记录所需的工作。谢谢@Wilduck。我对日志不是很感兴趣。我想在满足某些条件时,以数学和交互方式检查几个变量的值。我当然可以将变量转储到磁盘并在以后检查它们,但这不允许我恢复执行,这有时是我想要的。这种类型的工作流在科学计算中很常见且功能强大(例如,MATLAB通过使用
键盘
语句来支持这一点),它允许人们以交互方式检查和可视化数据,而无需完全中断或重新初始化程序。我明白了,这是有意义的。我将保留我的答案,因为它可能对稍后在这个问题上结结巴巴的人有用,但我个人恐怕没有任何进一步的建议。祝你好运。谢谢,但不清楚第一个解决方案如何允许我指定断点的可能位置。至于第二个,我将如何实际使用该选项?最后,据我所知,
pdb
不提供IPython用于内省等的相同功能。是否正确?运行调试器后,您可以使用
b
pdb命令定义断点。谢谢@Wildluck。这肯定很有用,尽管我对一些不需要指定行号的东西感兴趣。@Arnon如何使用
set_trace()
;哪个
设置跟踪
?纯旧的
ipdb.set_trace()
生成,建议使用
Tracer()()
!哦,可能是看到了Pdb.set_trace()或者;描述了IPython.core.debugger.set_trace,但我没有这个函数。链接的文档是针对IPython 6的(它只支持Python 3),我怀疑您使用的是旧版本
IPython.core.debugger.Tracer仍然存在并在IPython 6中工作,即使已弃用。我想你可以继续使用它一段时间,直到它被从代码库中删除。哈哈,这是真的,我使用的是
Tracer
,不过,希望有人能描述一下推荐的替代方案