import io
import sys
from enum import Enum
class Tee(io.StringIO):
class Source(Enum):
STDOUT = 1
STDERR = 2
def __init__(self, clone=Source.STDOUT, *args, **kwargs):
super().__init__(*args, **kwargs)
self._clone = clone
if clone == Tee.Source.STDOUT:
self._out = sys.stdout
elif clone == Tee.Source.STDERR:
self._out = sys.stderr
else:
raise ValueError("Clone has to be STDOUT or STDERR.")
def write(self, *args, **kwargs):
self._out.write(*args, **kwargs)
return super().write(*args, **kwargs)
def __enter__(self):
if self._clone == Tee.Source.STDOUT:
sys.stdout = self
else:
sys.stderr = self
self.seek(io.SEEK_END)
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if self._clone == Tee.Source.STDOUT:
sys.stdout = self._out
else:
sys.stderr = self._out
self.seek(0)
return False
基本上,它与马克西姆·马尔可夫在评论中所说的完全相同,但有一点不同。我通常不想暂停任何输出,所以我写了这个
Tee
它捕获所有在stdout(或stderr)上运行的文本,立即将其打印并保存到缓冲区中供以后使用。它还负责“修复”
sys.stdout
with
块
用法示例:
if __name__ == "__main__":
with Tee() as tee:
print("Hello World!")
print(tee.read())
有一些缺点,比如没有额外的代码,你就不能使用
tee.read()
with区块内。但在我的例子中,我总是需要处理整个块的输出。