2013-01-07 49 views
4

可能重複:
Can I redirect the stdout in python into some sort of string buffer?我怎樣才能重定向功能的打印輸出在python

我有Python中的功能,打印的東西到標準輸出

def foo(): 
    print("some text") 

我想將在這個函數中打印的文本'重定向'到一個變量中,例如'wrap'此功能或任何這樣的文本存儲在一個變量:

text = wrapper(foo) 

有沒有一種可靠的方法來臨時更改sys.stdout或打開變量作爲FileObject,還是其他什麼東西?

+0

Python 3中,我相信? –

+0

爲什麼不簡單地使用自己的打印功能? – phant0m

+0

函數定義給出,我不能函數本身。 – Alex

回答

16
>>> 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 

我已經看到這種情況甚至更好 - 您可以創建一個context manager到標準輸出設置成任何你想要的,當你進入情境,然後有上下文管理器復位標準輸出,當你__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() 

注:

在python3.x,StringIO.StringIO已經轉移到io.StringIO。此外,在python2.x上,cStringIO.StringIO可能會稍微更高性能。

+3

對於上下文管理器的建議,這可能是最乾淨的方法。 – l4mpi

+0

@ l4mpi:請參閱[PEP 0343](http://www.python.org/dev/peps/pep-0343/)中的「暫時重定向標準輸出」。還有一些可能會讓你感興趣的其他例子。 – martineau

7

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

B = [] 

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

def A(): 
    print("example") 

A() 

>>> B 
['example'] 

如果由於某種原因,你需要內置的打印回,只是做:

from builtins import print