如何在python中重定向函数的打印输出

Ale*_*lex 5 python printing stdout function

可能重复:
我可以将python中的stdout重定向到某种字符串缓冲区吗?

我在python中有一个函数,可以在标准输出中输出内容

def foo():
    print("some text")
Run Code Online (Sandbox Code Playgroud)

我想将此函数中正在打印的文本"重定向"为变量,即"包装"此函数或其他任何内容,以便将文本存储在变量中:

text = wrapper(foo)
Run Code Online (Sandbox Code Playgroud)

有没有一种强大的方法来临时更改sys.stdout或打开变量作为一个FileObject或其他什么?

mgi*_*son 19

对于python3.4 +,标准库中有一个上下文管理器.

with contextlib.redirect_stdout(file_like_object):
    ...
Run Code Online (Sandbox Code Playgroud)

这部分答案已经更新,但主要是针对那些仍然陷入python2.x世界的人

如果你坚持使用旧版本的python,那么这个上下文管理器并不难写.关键是你可以更新sys.stdout到你想要的任何类文件对象(这是print写入的内容):

>>> import sys
>>> import StringIO
>>> stdout = sys.stdout  # keep a handle on the real standard output
>>> sys.stdout = StringIO.StringIO() # Choose a file-like object to write to
>>> foo() 
>>> sys.stdout = stdout
>>> foo()
bar
Run Code Online (Sandbox Code Playgroud)

创建上下文管理器以在输入上下文时将stdout设置为您想要的任何内容,然后让上下文管理器在上下文时重置stdout __exit__.

这是一个contextlib用于创建上下文管理器的简单示例:

import contextlib
import sys

@contextlib.contextmanager
def stdout_redirect(where):
    sys.stdout = where
    try:
        yield where
    finally:
        sys.stdout = sys.__stdout__

def foo():
    print 'bar'

# Examples with StringIO
import StringIO

with stdout_redirect(StringIO.StringIO()) as new_stdout:
    foo()

new_stdout.seek(0)
print "data from new_stdout:",new_stdout.read()

new_stdout1 = StringIO.StringIO()
with stdout_redirect(new_stdout1):
    foo()

new_stdout1.seek(0)
print "data from new_stdout1:",new_stdout1.read()

# Now with a file object:
with open('new_stdout') as f:
    with stdout_redirect(f):
        foo()

# Just to prove that we actually did put stdout back as we were supposed to
print "Now calling foo without context"
foo()
Run Code Online (Sandbox Code Playgroud)

注意:

在python3.x上,StringIO.StringIO已移至io.StringIO.另外,在python2.x上,cStringIO.StringIO性能可能略高一些.

  • 上下文管理器建议+1,这可能是最干净的方法. (3认同)

Fre*_*nan 7

在Python 3.x中,您可以重新定义print.

B = []

def print(str):
    global B
    B.append(str)

def A():
    print("example")

A()

>>> B
['example']
Run Code Online (Sandbox Code Playgroud)

如果出于某种原因需要内置打印件,请执行以下操作:

from builtins import print
Run Code Online (Sandbox Code Playgroud)