-
Notifications
You must be signed in to change notification settings - Fork 0
/
thread_printing.py
46 lines (34 loc) · 1.44 KB
/
thread_printing.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
"""Module which allows each thread to print to its own file specified in the printer object's thread_files dictionary"""
import threading, sys, io
class ThreadPrinter(io.TextIOWrapper):
def __init__(self):
self.thread_files = {}
def add_thread(self, name, outfile):
self.thread_files[name]=outfile
def write(self, value):
try:
outfile = self.outfile() #If you forget to add the thread this will fail
outfile.write(value)
outfile.flush()
except:
sys.__stdout__.write(value) #write to stdout if you can't write to the file
sys.__stdout__.flush()
def __del__(self):
sys.stdout = sys.__stdout__
def __repr__(self):
return "ThreadPrinter" #So that errors can be traced back to this class
def outfile(self):
return self.thread_files[threading.currentThread().name]
def flush(self):
if not threading.enumerate(): #When the program closes one final flush is called, so we'll get errors unless we handle that by checking whether the flush is being called after all the threads are closed
return
else:
self.outfile().flush()
def closeThreadFile(threadname):
if not printer.thread_files[threadname].closed:
print("closing thread %s" % threadname)
printer.thread_files[threadname].close()
printer = ThreadPrinter()
main_name = threading.currentThread().name
printer.add_thread(main_name, sys.__stdout__) #keep the main thread printing to the standard output
sys.stdout=printer #print() is now a proxy to printer.write()