[从IPython Jupyter Notebook启动后台作业时,如何使打印输出显示在从其启动的单元中,而不是在当前正在使用的单元中?
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
documentation状态:
所有正在运行的线程共享相同的标准输出。因此,如果您的后台作业生成了输出,那么它将输出到您当前正在编写的所有内容之上。因此,最好将后台作业与无声功能配合使用,后者只需返回其输出即可。
在IPython(2011年10月)的GitHub pull request IPython.lib.backgoundjobs.BackgroundJobManager.new
中,开发人员讨论了此问题并得出结论,#856。因此,他们决定使用keeping the output in the original cell would be difficult to implement,在最新版本(撰写本文时为7.9.0)中,该问题尚未解决。
同时,一种解决方法是将输出存储在变量中,或者将输出写入/ table the idea到文件中,并在后台作业完成后打印/ pickle。
@ Peter其他答案解决了使用pickle或Output文件执行此操作的方法,我想建议其他方法。我建议您应该在父窗口中启动打印操作。当在子进程窗口中达到特定的执行条件时,则将这些值返回给父函数中的打印功能。
使用display打印父单元格中的值。这将输出和视觉效果打印在同一单元格中。
虽然这不是我的问题的直接答案,因为它不能与print命令一起使用,但我确实设法部分解决了我的问题,因为我可以在后面进行图形更新(因此可以记录任何类型的图形上的数据,无需重新运行。
以下基于%matplotlib inline
的一些概念验证代码
What is the currently correct way to dynamically update plots in Jupyter/iPython?
尽管此命令正在运行,但在另一个单元格中键入1 + 1不会中断图形的更新。对我来说,这是一个改变游戏规则的东西,所以如果有人帮助,我会予以张贴。