python 3, subclassing TextIOWrapper.

R. David Murray rdmurray at bitdance.com
Sun Mar 22 19:11:37 CET 2009


"Gabriel Genellina" <gagsl-py2 at yahoo.com.ar> wrote:
> En Sat, 21 Mar 2009 23:58:07 -0300, <lambertdw at corning.com> escribió:
> > import re
> > import io
> >
> > class file(io.TextIOWrapper):
> >
> >     '''
> >         Enhance TextIO.  Streams have many sources,
> >         a file name is insufficient.
> >     '''
> >
> >     def __init__(self,stream):
> >         #self.stream = stream
> >         super().__init__(stream.buffer)
> >
> >
> > print(file(open('p.py')).read())
> 
> You're taking a shortcut (the open() builtin) that isn't valid here.
> 
> open() creates a "raw" FileIO object, then a BufferedReader, and finally  
> returns a TextIOWrapper. Each of those has a reference to the previous  
> object, and delegates many calls to it. In particular, close() propagates  
> down to FileIO to close the OS file descriptor.
> 
> In your example, you call open() to create a TextIOWrapper object that is  
> discarded as soon as the open() call finishes - because you only hold a  
> reference to the intermediate buffer. The destructor calls close(), and  
> the underlying OS file descriptor is closed.
> 
> So, if you're not interested in the TextIOWrapper object, don't create it  
> in the first place. That means, don't use the open() shortcut and build  
> the required pieces yourself.
> 
> ---
> 
> There is another alternative that relies on undocumented behaviour: use  
> open to create a *binary* file and wrap the resulting BufferedReader  
> object in your own TextIOWrapper.
> 
> import io
> 
> class file(io.TextIOWrapper):
>       def __init__(self, buffer):
>           super().__init__(buffer)
> 
> print(file(open('p.py','rb')).read())

I'm wondering if what we really need here is either some way to tell open
to use a specified subclass(s) instead of the default ones, or perhaps
an 'open factory' function that would yield such an open function that
otherwise is identical to the default open.

What's the standard python idiom for when consumer code should be
able to specialize the classes used to create objects returned from
a called package?  (I'm tempted to say monkey patching the module,
but that can't be optimal :)

--
R. David Murray           http://www.bitdance.com




More information about the Python-list mailing list