Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pythons 'print' statement doesn't call the .write() method?

I thought the print statement just called the .write() method on the sys.stdout (by default) object.

but having written a subclass like this:

import time

class logfile(file):
    def __init__(self, *args, **kwargs):
        file.__init__(self, *args, **kwargs)

    def write(self, logstr):
        if logstr[-1] != '\n': logstr += '\n'
        super(logfile, self).write(time.strftime('%D-%T ') + str(logstr))

It seems to work if I create a logfile object and call the write method, but when trying to change the sys.stdout object to an instance of the logfile it appears as though print isn't calling write. Maybe writelines?

Using this:

#!/usr/bin/python

from myfile import logfile
import sys

sys.stdout = logfile('somefile', 'w')

print 'this is a test'
sys.stdout.write('this is another test')

My output file 'somefile' contains:

this is a test
08/10/11-16:59:47 this is another test

You can see the first line in the output file is what I tried to print and the second line is what was used in sys.stdout.write

I thought print just called the write method- clearly I'm missing something basic.

like image 697
tMC Avatar asked Aug 10 '11 21:08

tMC


1 Answers

Apparently this is an limitation of the implementation of Python 2 where print is a statement rather than an expression with side-effects (as it is in Python 3).

I rewrote the code to something that works in Python 3:

from io import FileIO
import time

class logfile(FileIO):
  def __init__(self, *args, **kwargs):
    FileIO.__init__(self, *args, **kwargs)

  def write(self, logstr):
    if logstr[-1] == '\n': logstr = logstr[:-1]
    super(logfile, self).write(bytes(time.strftime('%D-%T ') + str(logstr), 'UTF-8'))

import sys

sys.stdout = logfile('somefile', 'w')

print("This is a test")
sys.stdout.write('this is another test')

As far as I know there is no way to create the same behaviour in Python 2.

I also tried using from __future__ import print_function but that made no difference.

like image 200
Hobblin Avatar answered Oct 25 '22 02:10

Hobblin