print doesn't respect file inheritance?

Lie Lie.1296 at gmail.com
Sat Jul 26 17:41:04 CEST 2008


On Jul 26, 8:50 am, bukzor <workithar... at gmail.com> wrote:
> I was trying to change the behaviour of print (tee all output to a
> temp file) by inheriting from file and overwriting sys.stdout, but it
> looks like print uses C-level stuff  to do its writes which bypasses
> the python object/inhertiance system. It looks like I need to use
> composition instead of inheritance, but thought this was strange
> enough to note.
>
> $python -V
> Python 2.5
>
> """A short demo script"""
> class notafile(file):
>     def __init__(self, *args, **kwargs):
>         readonly = ['closed', '__class__', 'encoding', 'mode', 'name',
> 'newlines', 'softspace']
>         file.__init__(self, *args, **kwargs)
>         for attr in dir(file):
>             if attr in readonly: continue
>             setattr(self, attr, None)
>
> def main():
>     n = notafile('/dev/stdout', "w")
>     print vars(n)
>
>     import sys
>     sys.stdout = n
>     print "Testing: 1, 2, 3..."
>
> output:
> {'__str__': None, 'xreadlines': None, 'readlines': None, 'flush':
> None, 'close': None, 'seek': None, '__init__': None, '__setattr__':
> None, '__reduce_ex__': None, '__new__': None, 'readinto': None,
> 'next': None, 'write': None, '__doc__': None, 'isatty': None,
> 'truncate': None, 'read': None, '__reduce__': None,
> '__getattribute__': None, '__iter__': None, 'readline': None,
> 'fileno': None, 'writelines': None, 'tell': None, '__delattr__': None,
> '__repr__': None, '__hash__': None}
> Testing: 1, 2, 3...

Use this:

class fakefile(object):
    def __init__(self, writeto, transformer):
        self.target = writeto
        self.transform = transformer
    def write(self, s):
        s = self.transform(s)
        self.target.write(s)
sys.stdout = fakefile(sys.stdout, lambda s: '"' + s + '"')

Inheriting from file is not the best way to do it since there is a
requirement that child class' interface must be compatible with the
parent class' interface, since the file-like object you're creating
must have extremely different interface than regular file, the best
way is to use Duck Typing, i.e. write a class that have .write()
method.



More information about the Python-list mailing list