来自 Jupyter Notebook 的标准输出重定向正在终端中登陆

stdout redirect from Jupyter notebook is landing in the terminal

所以我试图将我的 Jupyter Notebook 中的一些单元格 stdout 重定向到一个文件,其余单元格的 this and then cancel it with this 。第一组单元格的输出如预期一样落入文件中。取消命令 sys.stdout = sys.__stdout__ 后的第二组单元格没有输出,似乎什么也没做,但后来我意识到它正在登陆笔记本启动的终端。

它在 Python 解释器中完美运行 Python:

(miniconda3-latest) cardamom@pegasus:~/Documents/project1 $ python
Python 3.6.0 |Continuum Analytics, Inc.| (default, Dec 23 2016, 12:22:00) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.stdout = open('stdout.txt', 'w')
>>> print("a")
>>> print("a")
>>> print("a")
>>> sys.stdout = sys.__stdout__
>>> print ("b")
b
>>> print ("b")
b
>>> print ("b")
b
>>> # lots of a's are in the file and no b's

Jupyter notebook 中的一个类似方法是在终端中给出这个:

[W 22:05:34.192 NotebookApp] 404 GET /nbextensions/widgets/notebook/js/extension.js (127.0.0.1) 1.71ms referer=http://localhost:8889/notebooks/test_stdout.ipynb
b
b
b

如何修改此代码,以便在重置后,b 出现在输出通常所在的单元格下方,而不是出现在终端中?

我看到的唯一解释是 sys.stdout 而不是 sys.__stdout__ 而是一个 rerouted/modified 文件对象,以便能够放置单元格中的数据(您的评论表明它是一个 ipykernel.iostream.OutStream 实例)。

因此,您应该存储 sys.stdout 的引用而不是重置为 sys.__stdout__

import sys
old_stdout = sys.stdout
sys.stdout = open('stdout.txt', 'w')
...
sys.stdout = old_stdout

请注意,此方法也适用于标准终端。

要处理中止执行的情况,您可以尝试处理错误。

import sys
nb_stdout = sys.stdout
with open("cell_output.deleteme", 'w') as cl_stdout:
    sys.stdout = cl_stdout
    try:
        print("hello, world!")
        raise Exception("goodbye, cruel world!")
    except Exception as e:
        print(e)
    finally:
        print("cell stdout")
        sys.stdout = nb_stdout
        print("notebook stdout")