写入多个流的包装器

5 投票
3 回答
1865 浏览
提问于 2025-04-17 12:16

在Python中,有没有简单的方法可以创建一个像文件一样的对象,用来写东西,而且这个对象实际上可以同时把内容输出到多个地方?比如,我想要这样的东西:

file1 = open("file1.txt", "w")
file2 = open("file2.txt", "w")
ostream = OStreamWrapper(file1, file2, sys.stdout)

#Write to both files and stdout at once:
ostream.write("ECHO!")

所以我想要的是一个叫做OStreamWrapper的东西。我知道自己写一个这样的东西其实很简单,但如果已经有现成的,我更愿意用现成的,这样就不用担心处理各种特殊情况了。

3 个回答

0

Logbook 是另一个选择,不过它的功能不仅仅如此。它的处理器更强大,你可以随意组合你想要的功能。

4
class OStreamWrapper(object):

    def __init__(self, *streams):
        self.streams = list(streams)

    def write(self, string):
        for stream in self.streams:
            stream.write(string)

    def writelines(self, lines):
        # If you want to use stream.writelines(), you have
        # to convert lines into a list/tuple as it could be
        # a generator.
        for line in lines:
            for stream in self.streams:
                stream.write(line)

    def flush(self):
        for stream in self.streams:
            stream.flush()

当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言解释清楚。

3

这是一个关于如何把所有公开的 file 函数包裹起来的方法:

import sys

def _call_for_all_streams(func_name):
    def wrapper(self, *args, **kwargs):
        result = []
        for stream in self._streams:
            func = getattr(stream, func_name)
            result.append(func(*args, **kwargs))
        return result
    return wrapper

class OStreamWrapper(object):
    def __init__(self, *streams):
        self._streams = streams

for method in filter(lambda x: not x.startswith('_'), dir(file)):
    setattr(OStreamWrapper, method, _call_for_all_streams(method))

if __name__ == '__main__':
    file1 = open("file1.txt", "w")
    file2 = open("file2.txt", "w")
    ostream = OStreamWrapper(file1, file2, sys.stdout)
    ostream.write("ECHO!")
    ostream.close()

不过这样做有点不太干净。

撰写回答