如何在启动它的单元格中打印 Jupyter 后台作业输出?



从 IPython Jupyter 笔记本启动后台作业时,如何使打印输出显示在启动它的单元格中,而不是显示在我当前正在使用的单元格中?

print()命令似乎打印到当前工作单元格中,而不是打印到启动后台作业的单元格中。有没有办法让它在启动它的单元格中很好地打印?这在运行多个后台作业集时尤其重要,因为要确定哪个作业集负责该行输出。

编辑:它发生在任何代码中,但这里有一个小片段来重现它:

from IPython.lib import backgroundjobs as bg
import time
def launchJob():
for i in range(100):
print('x')
time.sleep(1)
jobs = bg.BackgroundJobManager()
for r in range(3):
jobs.new("launchJob()")

这完全符合您的期望,每秒在单元格下方的输出中打印 3 个 X。现在转到下一个单元格并键入1+1并执行它。输出 2 出现,但任何剩余的 x 也会打印在这个新单元格中,而不是原始单元格中。

我正在寻找一种方法来明确告诉我的工作始终打印到执行它的原始单元格,例如在后台获取某种日志,或在后台生成一堆绘图,或者我想要的任何类型的数据在一个地方,而不是出现在我的笔记本上。

IPython.lib.backgoundjobs.BackgroundJobManager.new文档指出:

所有运行的线程共享相同的标准输出。因此,如果您的后台作业生成输出,它将出现在您当前正在编写的任何内容之上。出于这个原因,后台作业最好与静默函数一起使用,这些函数只是返回它们的输出。

在 IPython 的 GitHub 拉取请求 #856(2011 年 10 月(中,开发人员讨论了这个问题,并得出结论,将输出保留在原始单元格中将难以实现。因此,他们决定提出这个想法,在最新版本(撰写本文时为 7.9.0(中,它仍未解决。

同时,解决方法可能是将输出存储在变量中,或者将输出写入/腌制到文件并在后台作业完成后打印/显示它。

虽然这不是对我问题的直接回答,因为它不适用于 print 命令,但我确实设法部分解决了我的问题,因为我可以在后面更新图形(因此可以记录任何类型的数据,而无需重新运行(。

下面的一些概念验证代码,基于目前在Jupyter/iPython中动态更新绘图的正确方法是什么?

%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
import time
from IPython.lib import backgroundjobs as bg
def pltsin(ax, colors=['b']):
x = np.linspace(0,1,100)
if ax.lines:
for line in ax.lines:
line.set_xdata(x)
y = np.random.random(size=(100,1))
line.set_ydata(y)
else:
for color in colors:
y = np.random.random(size=(100,1))
ax.plot(x, y, color)
fig.canvas.draw()
fig,ax = plt.subplots(1,1)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_xlim(0,1)
ax.set_ylim(0,1)
def launchJob():
for i in range(100):
pltsin(ax, ['b', 'r'])
time.sleep(1)
jobs = bg.BackgroundJobManager()
jobs.new("launchJob()")

在运行此操作时,在另一个单元格中键入 1+1 不会中断图形的更新。对我来说,这是一个游戏规则的改变者,所以我会发布这个,以防有人从中得到帮助。

@Peter 由于其他答案解决了使用泡菜或输出文件执行此操作的方法,因此我想建议替代方法。 我建议您在父窗口中启动打印操作。当在子进程窗口中达到特定的执行条件时,将这些值返回到父进程中的打印函数。

使用%matplotlib inline打印父级单元格中的值。这将在同一单元格中打印输出和视觉对象。

最新更新