我用這一個在我的項目之一:
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)的文本,立即打印並保存到緩衝區以備後用。當代碼退出with
塊時,它也會關注「修復」sys.stdout
。
使用的例子:
if __name__ == "__main__":
with Tee() as tee:
print("Hello World!")
print(tee.read())
有喜歡無需額外的代碼你不能用塊內的使用tee.read()
一些缺點。但在我的情況下,我總是需要處理整個塊的輸出。
您需要用您自己的包裝器替換sys.stdout,該包裝器將所有寫入並傳遞到原始sys.stdout。 –
@MaksymMarkov是的,我認爲這是真正的解決方案,這是我在我的問題中的代碼片斷得到的。雖然我希望像這樣的東西已經被編寫和成熟,或者已經是Python的內置函數。 – KDecker