我知道如何将打印重定向到文件。
import sys
orig_stdout = sys.stdout
f = file('out.txt', 'w')
sys.stdout = f
for i in range(2):
print ('i = ', i)
sys.stdout = orig_stdout
f.close()
我需要做同样的事情但是没有文件:将打印输出保留在字符串列表中。如何在Py3k中完成?
编辑:我可以在中间部分进行第三方打印,而不是我自己的打印,因此代码必须是通用的“print()”通用。
答案 0 :(得分:14)
import sys
class ListStream:
def __init__(self):
self.data = []
def write(self, s):
self.data.append(s)
sys.stdout = x = ListStream()
for i in range(2):
print ('i = ', i)
sys.stdout = sys.__stdout__
print(x.data)
产量
['i = ', ' ', '0', '\n', 'i = ', ' ', '1', '\n']
提示:您无需保存原始sys.stdout
orig_stdout = sys.stdout
因为sys.stdout
可以通过
sys.stdout = sys.__stdout__
您还可以通过将ListStream
设置为上下文管理器来添加一些语法糖:
import sys
class ListStream:
def __init__(self):
self.data = []
def write(self, s):
self.data.append(s)
def __enter__(self):
sys.stdout = self
return self
def __exit__(self, ext_type, exc_value, traceback):
sys.stdout = sys.__stdout__
通过添加__enter__
和__exit__
方法,您现在可以在ListStream
中使用with-statement
,会自动重置sys.stdout
当Python退出with-suite
:
with ListStream() as x:
for i in range(2):
print ('i = ', i)
print(x.data)
答案 1 :(得分:5)
我认为最简单的方法是使用sys.stdout
实例替换TextIOWrapper
(只是StringIO
),而不是滚动自己的类,而是保留对它的引用:
import sys
from io import StringIO
s = StringIO()
sys.stdout = s
print('yo')
print('this is stuff')
print('hi')
s.getvalue()
Out[38]: 'yo\nthis is stuff\nhi\n'
s.getvalue().splitlines()
Out[39]: ['yo', 'this is stuff', 'hi']
正如@unutbu所说,您可以使用sys.stdout = sys.__stdout__
恢复原始标准输出;我特别喜欢使用上下文管理器暂时将stdout重定向到你想要的位置。
答案 2 :(得分:1)
当我需要构建ncurses
应用程序时,我经常这样做:
import sys
# in this wrapper class you can use a string list instead of a full string like I'm doing
class StdOutWrapper:
lines = []
def write(self,txt):
self.lines.append(txt)
# here is a method so you can get stuff out of your wrapper class
# I am rebuilding the text, but you can do whatever you want!
def get_text(self,beg,end):
return '\n'.join(self.lines)
mystdout = StdOutWrapper()
sys.stdout = mystdout
sys.stderr = mystdout
# do your stuff here that needs to be printed out in a string list
for i in range(2):
print ('i = ', i)
# you don't need to make your variable to cache the `stdout`/`stderr` as they still exist
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
它与python 3和python 2一起工作正常。
答案 3 :(得分:0)
我会编写一个函数来为你完成,而不是试图将stdout
重定向到一个列表(我认为它无论如何都不会起作用,但不要引用我的话)。< / p>
def lprint(text):
global string_list
try: string_list.append(text)
except NameError as e:
string_list = [text]
for i in range(2):
lprint ("i = {}".format(i))
print(string_list)
[OUT]: ["i = 0","i = 1"]