简短的回答是你不能。不容易。以下enhancement proposal 可以涵盖 IPython/Jupyter 协议的用例之一。虽然它还没有被接受,也不会很快发生。
(挥手)原因是,当使用 Python 时,您可以对 sys.stdin/sys.stdout/sys.stderr 进行猴子补丁并写入类似文件的接口,该接口重定向以执行“正确的事情”™,尽管当它是一个 fortran/c/... 函数,它们通常会直接打开原始流对应的文件句柄,而你不能在事后更改。
唯一的解决方案是控制进程如何启动,并提前更改文件描述符,因此提出了“内核 nany”。
让我们发展(在 OP 进一步问题之后)。
Python print 是一个不直接打印到标准输出的函数,除非另有说明,它实际上会写入 sys.stdout。如果你签入一个普通的 python shell:
>>> import sys
>>> sys.stdout
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
你可以看到它是一个文件句柄的直接包装器。
如果您在笔记本中执行相同操作(而不是在 IPython 终端中,那是另一回事),您将看到 <ipykernel.iostream.OutStream at 0x104602be0>,它是围绕 ZMQ 协议的代理对象。在 IPython 内核中,先前的流存储在 sys.__stdout__ 中,因此您可以四处玩耍并尝试
sys.__stdout__.write('Hello StackOverflow\n')
这将在您的笔记本服务器终端打印“Hello Stackoverflow”。
不要忘记触发流被刷新的\n。
并不是说这不是 Jupyter 行为,而是 IPython 行为。只要你通过 ZMQ 发送标准输出,Jupyter 方面并不关心你是怎么做的。 Haskell 内核很可能通过提供它自己的io 模块来做同样的事情。
捕获进程stdout 是一种解决方案(内核保姆提案涵盖),但它有其自身的缺点。在 Python 级别重定向更简单,因为 sys.stdout 就是为此而设计的。
这种行为既不是错误也不是“功能”,有人可能会争辩说 subprocess/f2py/pyc 等...应该能够处理非标准 stdout/stderr 作为参数,而 nanny是一种解决这些情况的解决方法,这将是