By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,660 Members | 1,105 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,660 IT Pros & Developers. It's quick & easy.

Issue of redirecting the stdout to both file and screen

P: n/a
I wanna print the log to both the screen and file, so I simulatered a
'tee'

class Tee(file):

def __init__(self, name, mode):
file.__init__(self, name, mode)
self.stdout = sys.stdout
sys.stdout = self

def __del__(self):
sys.stdout = self.stdout
self.close()

def write(self, data):
file.write(self, data)
self.stdout.write(data)

Tee('logfile', 'w')
print >>sys.stdout, 'abcdefg'

I found that it only output to the file, nothing to screen. Why?
It seems the 'write' function was not called when I *print* something.

May 28 '07 #1
Share this Question
Share on Google+
5 Replies


P: n/a
人言落日是天涯,望极天涯不见家 wrote:
I wanna print the log to both the screen and file, so I simulatered a
'tee'

class Tee(file):

def __init__(self, name, mode):
file.__init__(self, name, mode)
self.stdout = sys.stdout
sys.stdout = self

def __del__(self):
sys.stdout = self.stdout
self.close()

def write(self, data):
file.write(self, data)
self.stdout.write(data)

Tee('logfile', 'w')
print >>sys.stdout, 'abcdefg'

I found that it only output to the file, nothing to screen. Why?
It seems the 'write' function was not called when I *print* something.
There are places in the C code of Python that do the equivalent of

if isinstance(file_like_object, file):
file.write(file_like_object, text)
else:
file_like_object.write(text)

Therefore you can't safely inherit from file. The workaround is to make your
own file-like object; yours would become

class Tee(object):
def __init__(self, name, mode):
self.file = open(name, mode)
self.stdout = sys.stdout
sys.stdout = self
def __del__(self):
sys.stdout = self.stdout
self.file.close()
def write(self, data):
self.file.write(data)
self.stdout.write(data)

Peter
May 28 '07 #2

P: n/a
En Mon, 28 May 2007 06:17:39 -0300, 人言落日是天涯,望极天涯不见家
<ke********@gmail.comescribió:
I wanna print the log to both the screen and file, so I simulatered a
'tee'

class Tee(file):

def __init__(self, name, mode):
file.__init__(self, name, mode)
self.stdout = sys.stdout
sys.stdout = self

def __del__(self):
sys.stdout = self.stdout
self.close()

def write(self, data):
file.write(self, data)
self.stdout.write(data)

Tee('logfile', 'w')
print >>sys.stdout, 'abcdefg'

I found that it only output to the file, nothing to screen. Why?
It seems the 'write' function was not called when I *print* something.
You create a Tee instance and it is immediately garbage collected. I'd
restore sys.stdout on Tee.close, not __del__ (you forgot to call the
inherited __del__ method, btw).
Mmm, doesn't work. I think there is an optimization somewhere: if it looks
like a real file object, it uses the original file write method, not yours.
The trick would be to use an object that does NOT inherit from file:

import sys
class TeeNoFile(object):
def __init__(self, name, mode):
self.file = open(name, mode)
self.stdout = sys.stdout
sys.stdout = self
def close(self):
if self.stdout is not None:
sys.stdout = self.stdout
self.stdout = None
if self.file is not None:
self.file.close()
self.file = None
def write(self, data):
self.file.write(data)
self.stdout.write(data)
def flush(self):
self.file.flush()
self.stdout.flush()
def __del__(self):
self.close()

tee=TeeNoFile('logfile', 'w')
print 'abcdefg'
print 'another line'
tee.close()
print 'screen only'
del tee # should do nothing

--
Gabriel Genellina

May 28 '07 #3

P: n/a
Gabriel Genellina wrote:
En Mon, 28 May 2007 06:17:39 -0300, ???????????????
<ke********@gmail.comescribi:
>I wanna print the log to both the screen and file, so I simulatered a
'tee'

class Tee(file):

def __init__(self, name, mode):
file.__init__(self, name, mode)
self.stdout = sys.stdout
sys.stdout = self

def __del__(self):
sys.stdout = self.stdout
self.close()

def write(self, data):
file.write(self, data)
self.stdout.write(data)

Tee('logfile', 'w')
print >>sys.stdout, 'abcdefg'

I found that it only output to the file, nothing to screen. Why?
It seems the 'write' function was not called when I *print* something.

You create a Tee instance and it is immediately garbage collected.
It is not garbage collected until the next assignment to sys.stdout.

Peter

May 28 '07 #4

P: n/a
En Mon, 28 May 2007 09:10:40 -0300, Peter Otten <__*******@web.de>
escribi:
Gabriel Genellina wrote:
>En Mon, 28 May 2007 06:17:39 -0300, ???????????????
<ke********@gmail.comescribi:
>> def __init__(self, name, mode):
file.__init__(self, name, mode)
self.stdout = sys.stdout
sys.stdout = self

Tee('logfile', 'w')
print >>sys.stdout, 'abcdefg'

I found that it only output to the file, nothing to screen. Why?
It seems the 'write' function was not called when I *print* something.

You create a Tee instance and it is immediately garbage collected.

It is not garbage collected until the next assignment to sys.stdout.
Yes, sorry, this was my first guess. Later I discovered the real reason
-you pointed it too-, I should have removed the whole first paragraph on
my reply.

--
Gabriel Genellina

May 28 '07 #5

P: n/a
I see. Many thanks to you!

May 29 '07 #6

This discussion thread is closed

Replies have been disabled for this discussion.