【问题标题】:how to print jupyter background job output in cell it was launched from?如何在启动它的单元格中打印 jupyter 后台作业输出?
【发布时间】:2020-01-14 05:02:18
【问题描述】:

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

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

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

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 都打印在这个新单元格中,而不是在原始单元格中。

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

【问题讨论】:

  • 能否提供重现问题的代码?
  • 添加了一些重现问题的代码。希望这会有所帮助。

标签: jupyter-notebook output cell background-process


【解决方案1】:

虽然它不能直接回答我的问题,因为它不适用于 print 命令,但我确实设法部分解决了我的问题,因为我可以在后面更新图表(因此可以记录任何类型无需重新运行即可获得有关它们的数据)。

下面的一些概念验证代码,基于What is the currently correct way to dynamically update plots in 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 不会中断图形的更新。对我来说,这改变了游戏规则,所以我会发布这个以防万一有人得到它的帮助。

【讨论】:

  • 这实际上帮助我为我的问题创建了一个解决方案,谢谢!我已经给你赏金了。
【解决方案2】:

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

使用%matplotlib inline 打印父单元格中的值。这会在同一个单元格中打印输出和视觉效果。

【讨论】:

  • 我不确定我明白你在说什么。您介意添加示例代码,还是指向相关阅读?
【解决方案3】:

IPython.lib.backgoundjobs.BackgroundJobManager.new documentation 声明:

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

在 IPython 的 GitHub pull request #856(2011 年 10 月)中,开发人员讨论了这个问题并得出结论为 keeping the output in the original cell would be difficult to implement。因此,他们决定table the idea 并且在最新版本(撰写本文时为 7.9.0)中仍未解决。

同时,一种解决方法可能是将输出存储在变量中,或者将输出写入/pickle 到文件并在后台作业完成后打印/display

【讨论】:

  • 感谢您查找此内容,很遗憾。关于解决方法:如果后台进程(不是我编写或控制的)是一个使用 print(...) 处理所有内容的 python 脚本,我可以将输出存储在变量/文件中吗?
  • 如果您无法控制后台进程本身,它会变得更加复杂。如果是常规进程,您将能够使用IPython.utils.capture.capture_output 捕获stdout。不幸的是,这似乎不适用于后台进程,我不知道任何其他解决方案。
猜你喜欢
  • 2022-11-20
  • 2019-05-30
  • 1970-01-01
  • 2016-10-23
  • 2020-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多