gpt4 book ai didi

python - 从 ipython 捕获库 f2py 调用 stdout

转载 作者:行者123 更新时间:2023-12-01 03:26:37 30 4
gpt4 key购买 nike

我正在使用带有 Python 3 内核的 Jupyter 笔记本。

如果我运行:

import scipy.optimize
scipy.optimize.minimize(
lambda _: 1,
0,
method='COBYLA',
options={'iprint': 1, 'disp': True, 'maxiter': 2})

我希望将诊断优化信息打印到 ipython 笔记本上。但是,这会打印到控制台。我怀疑是这种情况,因为优化例程是在 Fortran 中实现的,并通过 f2py 在 scipy 中接口(interface)。 COBYLA Fortran 文件执行实际打印。

如何将 Fortran 子例程输出传送到 ipython 笔记本?据我了解,它应该与调用编译的 C 函数相同 - 那么为什么标准输出不共享?

最佳答案

简单的回答是你不能。不容易。以下用例可能涵盖的用例之一 enhancement proposal IPython/Jupyter 协议(protocol)。尽管它尚未被接受,也不会很快发生。

(挥手)原因是,当使用Python时,您可以monkeypatch sys.stdin/sys.stdout/sys.stderr并写入一个类似文件的接口(interface),该接口(interface)重定向以执行“正确的事情”™,尽管当它是fortran/c/... 函数,它们通常会直接打开与原始流对应的文件句柄,并且事后您无法更改它。

唯一的解决方案是控制进程的启动方式,并提前更改文件描述符,因此提出了“kernel 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 协议(protocol)的 Proxy 对象。在 IPython 内核中,先前的流存储在 sys.__stdout__ 中。所以你可以尝试一下

sys.__stdout__.write('Hello StackOverflow\n')

这将在笔记本服务器的终端中打印“Hello Stackoverflow”。不要忘记\n这会触发流被刷新。

这并不是 Jupyter 行为,而是 IPython 行为。 Jupyter 端并不关心你如何做,只要你通过 ZMQ 发送 stdout 即可。 Haskell 内核可能通过提供它自己的 io 来执行相同的操作。模块。

捕获进程stdout是一种解决方案(内核保姆提案涵盖的),但它有其自身的缺点。在 Python 级别重定向更简单,如 sys.stdout就是为此而生的。

这种行为既不是错误也不是“功能”,人们可能会认为 subprocess/f2py/pyc 等...应该能够处理非标准 stdout/stderr 作为参数,并且 nanny是帮助解决这些情况的解决方法,这将是

关于python - 从 ipython 捕获库 f2py 调用 stdout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41350116/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com