Returning a custom file object (Python 3)

Steven D'Aprano steve+comp.lang.python at pearwood.info
Thu May 28 03:04:18 EDT 2015


On Thursday 28 May 2015 15:49, Chris Angelico wrote:

> ... but I don't think replacing all of open() is what Steven has in
> mind; it's a function that does a lot of work, most of which is what's
> wanted.

Correct. If I wanted to replace open(), I would have just shadowed it, or 
monkey-patched it, or just used myopen().

I want open() to return my own subclass instead of the standard one. And I 
think you have the solution I was looking for:


> Depending on how brutal you want to be, though, you _could_ hack around
> it.
> 
>>>> from io import TextIOWrapper
>>>> class MyFile(TextIOWrapper):
> ...     def demo(self): print("Hello, world!")
> ...
>>>> f = open("/tmp/dummy", "w", encoding="utf-8")
>>>> f
> <_io.TextIOWrapper name='/tmp/dummy' mode='w' encoding='utf-8'>
>>>> f.__class__
> <class '_io.TextIOWrapper'>
>>>> f.__class__ = MyFile
>>>> f.demo()
> Hello, world!
> 
> This does appear to work. Whether or not it's a good idea is a
> separate question.


And this is EXACTLY the sort of use-case that having __class__ be writable 
is intended to solve. So this is exactly the solution I was after, thank 
you. Er... except for one little problem... in Python 3.3:

py> f = open("/tmp/a", "r")
py> f.__class__ = MyFile
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __class__ assignment: only for heap types


So it doesn't work for me. What version of Python are you using?



-- 
Steve




More information about the Python-list mailing list