我在这里有点问题。我有一个Python脚本,它调用从C ++编译的二进制文件。 Python脚本有自己的一组输出(标准输出和错误),这些输出很容易禁用。 C ++二进制文件也有自己的输出集(标准输出和错误,以及其他输出);来源可以改变,但我不是原作者。这是一个问题,因为我不想在我的最终程序中输出C ++,我也不希望将来的用户需要编辑C ++源代码。
我希望能够做的是使用一些Python方法来捕获发送到标准输出或错误的C ++代码输出。这可能吗?如果是这样,有人会指出我正确的方向吗?
谢谢!
答案 0 :(得分:8)
一种方法是:
stdout
在python中复制stderr
和os.dup
的文件描述符。stdout
(来自C的stderr
)重定向原始reopen
和stdio
,以便写入您选择的文件。注意:reopen
不能直接从python中获得,但您应该能够像下面的示例中那样调用它,或者使用任何其他可用的包装器。
完成此操作后:
cout
和cerr
的每次写入都会写入输出文件。print
语句都会写入输出文件。但是,由于原始描述符是重复的,您仍然可以(参见下面的示例):
stdout
和stderr
sdout.write
/ stdout.err
logging
参数stream
方法
以下代码使用instant库来测试使用SWIG包装到python中的真实C ++代码,它应该类似于您拥有的库:
import sys, os
import logging
from instant import inline
print 'This is printed from python to stdout'
stdout = os.fdopen(os.dup(sys.stdout.fileno()), 'w')
stderr = os.fdopen(os.dup(sys.stderr.fileno()), 'w')
logging.basicConfig(stream=stderr, level=logging.DEBUG)
redirect = inline("""
void redirect(void) {
freopen("my_stdout.txt", "w", stdout);
freopen("my_stderr.txt", "w", stderr);
}
""")
redirect()
cout = inline("""
void cout(void) {
std::cout << "This is written from C++ to my_stdout.txt" << std::endl;
std::cerr << "This is written from C++ to my_stderr.txt" << std::endl;
}
""")
cout()
print 'This is written from python to my_stdout.txt'
stdout.write('This is printed from python to stdout\n')
stderr.write('This is printed from python to stderr\n')
logging.info('This is printed to stderr from python using logging')
此示例的输出为:
$ python test.py
This is printed from python to stdout
This is printed from python to stdout
This is printed from python to stderr
INFO:root:This is printed to stderr from python using logging
$ cat my_stdout.txt
This is written from C++ to my_stdout.txt
This is written from python to my_stdout.txt
$ cat my_stderr.txt
This is written from C++ to my_stderr.txt
注意:第一次执行代码时,您可能会收到gcc
个编译消息(我已删除它们以使示例更清晰)。
答案 1 :(得分:0)
您使用subprocess
编译C ++吗?如果是这样,您可以设置stderr和stdout的位置:
nowhere = StringIO()
subprocess.call("exit 1", shell=True, stdout=nowhere, stderr=nowhere)