Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Issue of redirecting the stdout to both file and screen

Reply
Thread Tools

Issue of redirecting the stdout to both file and screen

 
 
=?gb2312?B?yMvR1MLkyNXKx8zs0cSjrM37vKvM7NHEsru8+7zS?=
Guest
Posts: n/a
 
      05-28-2007
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.

 
Reply With Quote
 
 
 
 
Peter Otten
Guest
Posts: n/a
 
      05-28-2007
人言落日是天涯,望极天涯不见家 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


 
Reply With Quote
 
 
 
 
Gabriel Genellina
Guest
Posts: n/a
 
      05-28-2007
En Mon, 28 May 2007 06:17:39 -0300, 人言落日是天涯,望极天涯不见家
<(E-Mail Removed)> escribió:

> 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

 
Reply With Quote
 
Peter Otten
Guest
Posts: n/a
 
      05-28-2007
Gabriel Genellina wrote:

> En Mon, 28 May 2007 06:17:39 -0300, ???????????????
> <(E-Mail Removed)> escribi:
>
>> 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

 
Reply With Quote
 
Gabriel Genellina
Guest
Posts: n/a
 
      05-28-2007
En Mon, 28 May 2007 09:10:40 -0300, Peter Otten <(E-Mail Removed)>
escribi:

> Gabriel Genellina wrote:
>
>> En Mon, 28 May 2007 06:17:39 -0300, ???????????????
>> <(E-Mail Removed)> escribi:
>>
>>> 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

 
Reply With Quote
 
=?gb2312?B?yMvR1MLkyNXKx8zs0cSjrM37vKvM7NHEsru8+7zS?=
Guest
Posts: n/a
 
      05-29-2007
I see. Many thanks to you!

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
redirecting output ruby and from stdout results in blank file comp.lang.ruby Ruby 4 01-11-2010 11:10 PM
redirecting stdout to a file as well as screen SamG Python 10 04-12-2007 11:57 AM
Problems redirecting STDOUT (NOT sys.stdout) to a pipe. Elad Python 0 03-19-2006 01:30 PM
script hangs when run from command line and redirecting stdout and stderr to file it_says_BALLS_on_your forehead Perl Misc 2 01-10-2006 11:31 AM
Ant redirecting stdout to a file while in a spawned java program Douwe Java 1 01-12-2004 02:16 AM



Advertisments