我想收集所有的列印內容并將它們保存在一個 txt 檔案中。我使用這個答案的方法來生成和收集日志。我也使用 a threading,因為在我的真實環境中,get_logs并且make_logs在不同的執行緒中。
import sys
import io
import time
import threading
import traceback
class MyThread(threading.Thread):
def __init__(self, func, args):
super(MyThread, self).__init__()
self.func = func
self.args = args
def run(self):
try:
self.result = self.func(*self.args)
except Exception as e:
f = traceback.format_exc()
print(f'{f}')
def get_result(self):
try:
return self.result
except Exception:
return None
def make_logs(delay):
for i in range(100):
print(i)
print("\n")
time.sleep(delay)
def get_logs(t1):
if t1.is_alive():
sys.stdout = old_stdout
whatWasPrinted = buffer.getvalue()
with open("output.txt", "w") as text_file:
text_file.write(whatWasPrinted)
time.sleep(1)
get_logs(t1)
def do_it():
t1 = MyThread(make_logs, args=(1,))
t2 = MyThread(get_logs, args=(t1,))
t1.start(), t2.start()
t1.join(), t2.join()
old_stdout = sys.stdout
sys.stdout = buffer = io.StringIO()
do_it()
但是,當我執行此代碼時,我只能將第一個 elment(0) 寫入 txt 檔案。有誰知道為什么?謝謝。
uj5u.com熱心網友回復:
您可以將 sys.stdout 設定為檔案物件以重定向輸出:
import sys
sys.stdout = open(PATH_TO_LOG_FILE, "w")
print('test')
do_it()
sys.stdout.close()
你也可以使用contextlib.redirect_stdout:(適用于 python 3.4 )
from contextlib import redirect_stdout
with open('help.txt', 'w') as f:
with redirect_stdout(f):
print('it now prints to `help.text`')
uj5u.com熱心網友回復:
您不需要兩個執行緒來捕獲前 N 秒 - 您可以撰寫一個類似檔案的物件,io.StringIO當它已經足夠時停止寫入任何支持物件(這里它只是派生但可以包裝另一個 IO)。
import contextlib
import io
import threading
import time
def make_logs(n, delay):
for i in range(n):
print(i)
print("\n")
time.sleep(delay)
class StdoutCapturer(io.StringIO):
def __init__(self, time_limit):
super().__init__()
self.time_limit = time_limit
# This could be initialized later, at the first write:
self.start_time = time.time()
def write(self, s: str) -> int:
elapsed = time.time() - self.start_time
if elapsed < self.time_limit:
return super().write(s)
return 0
if __name__ == "__main__":
sio = StdoutCapturer(time_limit=3.1)
with contextlib.redirect_stdout(sio):
t = threading.Thread(target=make_logs, args=(5, 1))
t.start()
t.join()
print(repr(sio.getvalue()))
這列印出來
'0\n\n\n1\n\n\n2\n\n\n3\n\n\n'
編輯
根據評論,我認為包裝另一個 IO 的含義并不清楚,所以這是一個將前 N 秒寫入檔案的變體......
class TimeLimitedFileWrapper(io.TextIOWrapper):
def __init__(self, raw_file, *, time_limit):
super().__init__(raw_file, encoding="utf-8")
self.start_time = time.time()
self.time_limit = time_limit
def write(self, s: str) -> int:
elapsed = time.time() - self.start_time
if elapsed < self.time_limit:
return super().write(s)
return 0
if __name__ == '__main__':
with open("foo.txt", "wb") as f:
with contextlib.redirect_stdout(TimeLimitedFileWrapper(raw_file=f, time_limit=3.1)):
t = threading.Thread(target=make_logs, args=(5, 1))
t.start()
t.join()
with open("foo.txt", "rb") as f:
print(repr(f.read()))
輸出是一樣的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/412429.html
標籤:
