print stream behavior

A

Andreas Kraemer

I don't understand the behavior of the print statement when streaming
to a "file-like" object. From the documentation at
http://www.python.org/doc/2.4.4/ref/print.html I understand that the
file-like object needs to have a write() method that - I assume - is
called when the print statement is invoked. However, the piece of code
below does not behave as I expect.

F subclasses file and overwrites its write() method (simply printing
out a message and then calling the superclass's write()). Calling
write directly works as expected, using print does not.

Can anybody shed some light on what's happening under the hood (or how
to make it work with "print")?

Thanks,
Andreas

Python 2.4.2 (#1, Jan 10 2008, 17:43:47)
[GCC 4.1.2 20070115 (prerelease) (SUSE Linux)] on linux2
Type "help", "copyright", "credits" or "license" for more information..... def write(self,str):
.... print 'writing to %s: %s' % (self.name,str)
.... file.write(self,str)
....
$ cat test.txt
hallogood bye
 
P

Peter Otten

Andreas said:
I don't understand the behavior of the print statement when streaming
to a "file-like" object. From the documentation at
http://www.python.org/doc/2.4.4/ref/print.html I understand that the
file-like object needs to have a write() method that - I assume - is
called when the print statement is invoked. However, the piece of code
below does not behave as I expect.

F subclasses file and overwrites its write() method (simply printing
out a message and then calling the superclass's write()). Calling
write directly works as expected, using print does not.

Can anybody shed some light on what's happening under the hood (or how
to make it work with "print")?

This is a longstanding quirk of the CPython implementation. The
PRINT_ITEM_TO opcode triggers a PyFile_WriteObject() call which in turn does
the C equivalent of

if isinstance(f, file):
file.write(f, s)
else:
write = getattr(f, "write")
write(s)

Therefore subclasses of file will always use file.write() when invoked via
'print'.

You can avoid that by writing a wrapper instead of a subclass:

class File(object):
def __init__(self, *args):
self._file = open(*args)
def write(self, s):
self._file.write(s)
# add other methods as needed

Peter
 
A

Andreas Kraemer

This is a longstanding quirk of the CPython implementation. The
PRINT_ITEM_TO opcode triggers a PyFile_WriteObject() call which in turn does
the C equivalent of

if isinstance(f, file):
   file.write(f, s)
else:
   write = getattr(f, "write")
   write(s)

Therefore subclasses of file will always use file.write() when invoked via
'print'.

You can avoid that by writing a wrapper instead of a subclass:

class File(object):
    def __init__(self, *args):
        self._file = open(*args)
    def write(self, s):
        self._file.write(s)
    # add other methods as needed

Peter

Thanks very much! That solves the mystery ...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,527
Members
44,999
Latest member
MakersCBDGummiesReview

Latest Threads

Top