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

Capture print output from a c-module in python

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

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

我找到了各种解决方案,例如 Capture stdout from a script in Python

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

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

此解决方案也不起作用

Python 将冻结在

out.stop()

ipython 也会冻结在

sys.stdout = StringIO()

这可能与它有关。

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

我不知道它是否应该相关,但我在 osx-64

上使用 conda 3.14.1

有时这可能是个问题,因为 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),您将不得不手动连接到它。

在此处 找到的子流程解决方案确实有效!

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]

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