steve-gregory
steve-gregory

Reputation: 7456

Redirecting python output to file prints two lines

Using the advice of another stack overflow question I wrote my own LogWriter class:

class LogWriter:
    def __init__(self, output, filename):
            self.output = output
            self.logfile = file(filename, 'a')

    def write(self, text):
            now = datetime.now()
            stamp = now.strftime("%Y-%m-%d - %I:%M:%S")
            text = "[%s] %s" % (stamp,text)
            if(DEBUG):
                    self.output.write(text)
                    self.output.flush()
            self.logfile.write(text)
            self.logfile.flush()

    def close(self):
            self.output.close()
            self.logfile.close()

However this is the output I recieve:

    >>logwriter = LogWriter(sys.stdout, LOG_FILENAME)
    >>sys.stdout = logwriter
    >>print "test"
    [2011-12-12 - 08:15:00] test[2011-12-12 - 08:15:00]

If i remove the line that modifies text and print just the original message, the class works as expected, printing to both the log file and stdout:

test

For some reason my timestamp is duplicated, and I can't figure out why. What is the proper way to fix this error in python?

EDIT: As aix has said below, I was making an assumption that print calls and write calls were one-to-one, but this isn't true. As a simple fix to continue using my LogWriter class I am now making the calls as follows:

...
def write(self, text):
            now = datetime.now()
            stamp = now.strftime("%Y-%m-%d - %I:%M:%S")
            text = "[%s] %s\n" % (stamp,text)
...
>>logwriter = LogWriter(sys.stdout, LOG_FILENAME)
>>logwriter.write("test")
[2011-12-12 - 08:38:55] test

Upvotes: 1

Views: 228

Answers (2)

Nick Bastin
Nick Bastin

Reputation: 31329

Try:

>>>print "test",

Possibly you are getting the implicit newline from print as a separate call to write(). Either way, the problem is that you're getting multiple calls to write() (as there is no guarantee how a caller uses write() - it could call it for every character if it liked).

Upvotes: 4

NPE
NPE

Reputation: 500357

You should not be assuming that a single print statement results in a single call to write(). Therefore I believe that the whole approach of producing a timestamp on every write() is flawed.

You could try to fix this by producing a timestamp at the start of each line (by looking for \n characters in text), but that doesn't strike me as being particularly elegant either.

Upvotes: 2

Related Questions