Reputation: 1786
I recenlty desired a bit of python code that would allow me to output to the console and a logfile with the same print statement. After googleing I found this website which offered an excellent solution. However, I would like to be able to flush the output buffer after each write in order to see it in the log file. How would I go about adding it into this class?
I have tried to following setups...
class output_file(object):
def __init__(self, stdout, filename):
silentremove(filename)
self.stdout = stdout
self.logfile = open(filename, "a")
def write(self, text):
self.stdout.write(text)
self.logfile.write(text)
sys.stdout.flush()
def flush(self):
sys.stdout.flush()
def close(self):
self.stdout.close()
self.logfile.close()
This was had a cyclic error which resulted in the flush function calling itself.
class output_file(object):
def __init__(self, stdout, filename):
silentremove(filename)
self.stdout = stdout
self.logfile = open(filename, "a")
def write(self, text):
self.stdout.write(text)
self.logfile.write(text)
self.stdout.flush()
def flush(self):
sys.stdout.flush()
def close(self):
self.stdout.close()
self.logfile.close()
This didn't flush it at all.
Upvotes: 0
Views: 5083
Reputation: 3340
The following reopens sys.stdout in unbuffered mode. Each stdout.write
and print
will be automatically flushed (i.e. printed to stdout) afterwards.
import sys
import os
# Flush STDOUT continuously
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
The third argument of os.fdopen is the buffering argument, 0
is unbuffered, 1
is line buffered and >1
will result in a buffer of (approximately) that size (in bytes), <0
will use the systems default.
UPDATE
With Python 3 unbuffered text is not allowed, i.e. the following
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
Will result in the error
ValueError: Can't have unbuffered text I/O
To use unbuffered I/O in python3, bytes can be used, i.e.
sys.stdout = os.fdopen(sys.stdout.fileno(), 'wb', 0)
Will work fine in python3.
Upvotes: 4