2011-12-13 113 views
3

我在这里有点问题。我有一个Python脚本,它调用从C++编译的二进制文件。 Python脚本有它自己的一组输出(标准输出和错误),这些输出很容易禁用。 C++二进制文件具有自己的一组输出(以标准输出和错误等);源可以改变,但我不是原作者。这是一个问题,因为我不想在最终的程序中输出C++,而且我也不希望将来的用户需要编辑C++源代码。从Python脚本控制C++输出

我希望能够做的是有一些Python方法,它将捕获发送到标准输出或错误的C++代码输出。这可能吗?如果是这样,有人能指出我正确的方向吗?

谢谢!要做到这一点

+0

这取决于您调用二进制文件的方式。例如,如果你使用的是os.system,你可以管输出,否则可能有一些方法需要研究。在脚本中写入的调用如何? – bcc32 2011-12-13 21:58:55

+0

对不起,我应该在消息体中发布它们:它们是通过Python接口导入的,所以Python认为它调用了其他Python模块。 – learner 2011-12-13 22:05:33

回答

8

一种方法是:使用os.dupstdoutstderr的文件描述符

  • 重复的蟒蛇。
  • 使用reopen(来自C的stdio)重定向原始文件stdoutstderr以写入您选择的文件。

注:reopen是不是从蟒蛇提供直接,但你应该能够调用它,如下面的例子或者利用现有的任何其他包装。

此步骤完成后:

  • 每写coutcerr在C++将写入到输出文件。
  • python中的每个print语句都会写入输出文件。

但是,由于原来的描述是重复的,你仍然可以(见下例):使用sdout.writestdout.err

  • 使用logging方法配置正确后

    • 打印到原来的stdout/stderrstream参数

    以下代码使用instant库测试是使用痛饮这应该是相似的,你有图书馆裹成蟒蛇真正的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编译消息(我已将它们删除以使示例更清晰)。

  • +0

    如果我明白你已经做了什么,这会将所有输出重定向到日志记录,包括Python和C++,对吧?如果是这样的话,那也可以,因为这个程序的有用输出实际上是写入文件的。 – learner 2011-12-13 23:09:47

    0

    您是否在使用subprocess来编译C++?如果是这样,您可以设置stderr和stdout的位置:

    nowhere = StringIO() 
    subprocess.call("exit 1", shell=True, stdout=nowhere, stderr=nowhere)