Issue of redirecting the stdout to both file and screen

Peter Otten __peter__ at web.de
Mon May 28 06:10:42 EDT 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





More information about the Python-list mailing list