当前位置: 代码迷 >> python >> 从 python 中的 c 模块捕获打印输出
  详细解决方案

从 python 中的 c 模块捕获打印输出

热度:47   发布时间:2023-06-13 14:18:07.0

我想将 pycosat 的这个详细输出存储到一个字符串中:

import pycosat
cnf = [[1, -5, 4], [-1, 5, 3, 4], [-3, -4]]
pycosat.solve(cnf,verbose=5)

我找到了各种解决方案,例如

然而,基于 stringIO() 的解决方案不会捕获 pycosat 输出。 输出正常打印,并捕获一个空字符串。

我认为这与 pycosat 绑定到 c-library picosat 的事实有关,但我不知道如何处理。

此解决方案也不起作用

Python 将冻结在

out.stop()

ipython 也将冻结在

sys.stdout = StringIO()

这可能与它有关。

我没有尝试使用使用 subprocess 的解决方案,因为我需要局部变量 cnf,并且将它传递到子进程中没有任何意义。

我不知道它是否相关,但我在 osx-64 上使用 conda 3.14.1

在这里找到的子流程解决方案 ,确实有效!

import subprocess
proc = subprocess.Popen(["python", "-c",
    "cnf = [[1, -5, 4], [-1, 5, 3, 4], [-3, -4]];\
    import pycosat;\
    pycosat.solve(cnf,verbose=5);"],
    stdout=subprocess.PIPE)
out = proc.communicate()[0]

我不喜欢程序传递的方式(作为 eval 字符串),但至少它是有效的。

有时这可能是一个问题,因为 Mac OS 只有虚拟终端,而真正的控制台是隐藏的。 所以 stdout 和 stderr 有时会表现得很奇怪。 (非常罕见的情况)

尝试改用 stderr:

from cStringIO import StringIO
import sys
import pycosat
cnf = [[1, -5, 4], [-1, 5, 3, 4], [-3, -4]]
sys.stderr = StringIO()
pycosat.solve(cnf,verbose=5)
solution = sys.stderr.getvalue()
sys.stderr = sys.__stderr__
print solution

如果这仍然对您没有好处,那么 pycosat 将使用另一个文件描述符作为其输出(既不是 stdout 也不是 stder),您将不得不手动连接到它。