python捕获另一个模块的打印输出

时间:2014-04-02 20:25:39

标签: python stdout

我想知道这在python中是否可行。

#module1
def test():
    print 'hey'

#module2
import module1

# *Without modifying module1* is there anyway to wrap this in module2 so that I can capture the
# print 'hey' inside a variable? apart from running module1 as a script?
module1.test() # prints to stdout

谢谢!

6 个答案:

答案 0 :(得分:17)

是的,您只需要将stdout重定向到符合stdout接口的内存缓冲区,您可以使用StringIO执行此操作。这适用于我:2.7:

import sys
import cStringIO

stdout_ = sys.stdout #Keep track of the previous value.
stream = cStringIO.StringIO()
sys.stdout = stream
print "hello" # Here you can do whatever you want, import module1, call test
sys.stdout = stdout_ # restore the previous stdout.
variable = stream.getvalue()  # This will get the "hello" string inside the variable

答案 1 :(得分:12)

是的,你可以。您需要控制sys.stdout。像这样:

import sys

stdout_ = sys.stdout #Keep track of the previous value.
sys.stdout = open('myoutputfile.txt', 'w') # Something here that provides a write method.
# calls to print, ie import module1
sys.stdout = stdout_ # restore the previous stdout.

答案 2 :(得分:4)

对于Python 3:

# redirect sys.stdout to a buffer
import sys, io
stdout = sys.stdout
sys.stdout = io.StringIO()

# call module that calls print()
import module1
module1.test()

# get output and restore sys.stdout
output = sys.stdout.getvalue()
sys.stdout = stdout

print(output)

答案 3 :(得分:3)

我不想负责修改sys.stdout,然后将其还原为以前的值。上面的答案没有任何finally:子句,将其集成到其他重要代码中可能很危险。

https://docs.python.org/3/library/contextlib.html

import contextlib, io

f = io.StringIO()
with contextlib.redirect_stdout(f):
    module1.test()
output = f.getvalue()

您可能想要具有重定向的标准输出的变量output。{p}

注意:此代码是从官方文档中删除的,并做了一些细微的修改(但已通过测试)。此答案的另一个版本已经在此处提供了一个几乎重复的问题:https://stackoverflow.com/a/22434594/1092940

我将答案留在这里,因为它比IMO中的其他解决方案要好得多。

答案 4 :(得分:1)

无需使用其他模块,只需使用具有write属性的类对象和一个输入,即可将其保存在另一个变量中。营地

CLASS:

class ExClass:
    def __init__(self):
        self.st = ''
    def write(self, o): #here o is the output that goes to stdout
        self.st += str(o)

主程序:

import sys
stdout_ = sys.stdout
var = ExClass()
sys.stdout = var

print("Hello") # these will not be pronted 
print("Hello2") # instead will be written in var.st

sys.stdout = stdout_

print(var.st) 

输出将为

Hello
Hello2

答案 5 :(得分:0)

将ftplib调试输出发送到日志记录模块

基于App.js回答所采用的方法,我能够将jimmy kumar ahalpara的调试输出捕获到ftplib中。 ftplib在日志记录模块之前,并且使用logging发出调试消息。

我尝试将打印功能重新分配给日志记录方法,但无法正常工作。下面的代码对我有用。

我应该认为这也可以与其他模块一起使用,但是不同模块的输出之间不会存在任何粒度,因为它将所有发送到print的内容捕获到同一记录器中。

stdout