将打印重定向到字符串列表?

2024-04-18 01:40:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我知道如何将打印重定向到文件。

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()”。


Tags: 文件inimporttxtforclosestdoutsys
3条回答

当我需要构建一个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上运行良好。

与其滚动您自己的类,我认为最简单的方法是用您保持引用的StringIO实例替换sys.stdout(这只是一个TextIOWrapper):

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;我特别喜欢使用上下文管理器将stdout临时重定向到您希望它转到的位置。

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成为contextmanager来添加一些语法糖:

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__方法,现在可以在with-statement中使用ListStream,当Python退出with-suite时,该方法将自动为您重置sys.stdout

with ListStream() as x:
    for i in range(2):
        print ('i = ', i)

print(x.data)

相关问题 更多 >