简体   繁体   中英

Why does this add an extra timestamp when printing?

I use below code add timestamp into print. but it is strange why it add two timestamp around message.

old_f = sys.stdout

class CFout:
    def write(self, x):
        old_f.write("%s %s " % (datetime.now().strftime("%d/%m/%Y %H:%M:%S:%f"), x))

sys.stdout = CFout()

When I print True . it output as below.

15/05/2015 05:42:02:121945 True 15/05/2015 05:42:02:121977

Before and after True , there are two timestamp.
why is this? I only want to add timestamp before True .

It's due to the fact that the print statement or function performs two calls to write , one to print the message ( 'True' ) and one for the ending newline or space.

You can see this using a script like the following:

import sys
from datetime import datetime

args = []

class CFout:
    def write(self, x):
        args.append(x)
        sys.__stdout__.write("%s %s " % (datetime.now().strftime("%d/%m/%Y %H:%M:%S:%f"), x))


sys.stdout = CFout()

print True
print False
print 1, 2, 3

sys.stdout = sys.__stdout__
print 'arguments were'
print args

Called results in:

$python2 prnt.py 
15/05/2015 08:07:03:171182 True 15/05/2015 08:07:03:171392 
 15/05/2015 08:07:03:171452 False 15/05/2015 08:07:03:171477 
 15/05/2015 08:07:03:171517 1 15/05/2015 08:07:03:171540   15/05/2015 08:07:03:171561 2 15/05/2015 08:07:03:171581   15/05/2015 08:07:03:171601 3 15/05/2015 08:07:03:171621 
 arguments were
['True', '\n', 'False', '\n', '1', ' ', '2', ' ', '3', '\n']

Note:

  • 'True' and '\\n' are the arguments for the two calls performed when doing print True .
  • 'False' and '\\n' are the arguments for the two calls performed when doing print False
  • '1' , ' ' , '2' , ' ' , '3' and '\\n' are the arguments performed when doing print 1,2,3 .

An other way of seeing this is by using exceptions:

>>> print 1, 1/0, 2
1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

Note: the 1 was still printed even though the 1/0 raised an exception. What python is doing is taking each single portion of the stuff to print, evaluating it and then calling write . Afterwards it calls write(' ') to print the space due to the comma and finally evaluates 1/0 which results in an exception.

In the same way print True first evaluates True , then calls write(str(True)) and finally calls write('\\n') to add the final newline.

If you want to propoerly attach a timestamp to messages you should use the logging module instead.

Base on @Bakuriu answer, I am using below code to achieve my object as I am confident that I will not use "\\n" in print message. :). I post here if others are also interesting.

old_f = sys.stdout
class CFout:
    def write(self, x):
        if x.find("\n") == -1:
            old_f.write("%s %s " % (datetime.now().strftime("%d/%m/%Y %H:%M:%S:%f"), x))
        else:
            old_f.write(x)
sys.stdout = CFout()

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