用python从c模块捕获打印输出
我想将pycosat的这个详细输出存储到一个字符串中:用python从c模块捕获打印输出,python,c,printing,binding,output,Python,C,Printing,Binding,Output,我想将pycosat的这个详细输出存储到一个字符串中: import pycosat cnf = [[1, -5, 4], [-1, 5, 3, 4], [-3, -4]] pycosat.solve(cnf,verbose=5) 我找到了各种各样的解决办法。 但是,基于stringIO()的解决方案不会捕获pycosat输出。输出正常打印,并捕获空字符串 我认为这与pycosat是c库picosat的绑定有关,但我不知道如何处理这个问题 这个解决方案也不起作用 巨蟒将冻结在 out.st
import pycosat
cnf = [[1, -5, 4], [-1, 5, 3, 4], [-3, -4]]
pycosat.solve(cnf,verbose=5)
我找到了各种各样的解决办法。
但是,基于stringIO()的解决方案不会捕获pycosat输出。输出正常打印,并捕获空字符串
我认为这与pycosat是c库picosat的绑定有关,但我不知道如何处理这个问题
这个解决方案也不起作用
巨蟒将冻结在
out.stop()
sys.stdout = StringIO()
ipython也将在晚上冻结
out.stop()
sys.stdout = StringIO()
这可能与此有关
我没有尝试使用使用subprocess的解决方案,因为我需要局部变量cnf,并且将其传递到subprocess中没有意义
我不知道它是否相关,但我正在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正在使用另一个filedescriptor作为其输出(既不是标准输出,也不是标准输出),您将不得不手动连接到它。这里找到的子流程解决方案确实有效
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 X内置Python上尝试过它,对吗?我没有,因为我没有在那里安装pycosat(由于包问题,我使用conda),不幸的是,这也没有捕获输出。您建议我手动连接到它。你的意思是我必须编辑绑定吗?在我看来,c文件中使用标准输出来打印您在使用标准输出处理块时所说的结果。所以它可能确实使用标准输出,但它通过FCNTL对终端进行了一些更改。因此,StringIO()不是一个无法应用的终端,它会阻塞。在这种情况下,您应该能够通过在sys.stdout中放入一些伪终端来愚弄pycosat。请参阅模块tty。它将在一端写入,您将从另一端读取。通过-手动-我的意思是,如果使用的另一个文件描述符不是sys.stdout或sys.stderr,而是桥接到它们,您将能够使用os.fdopen()包装它,然后以某种方式重定向它。但开放新的终端并不常见。要查看是否创建了任何其他tty,请在导入pycosat后查看所有打开的文件。命令lsof在Linux上,我现在没有在Mac上启动检查,也许是一样的。