简体   繁体   中英

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

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).

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM