I am trying to make a method in a class which returns an object that behaves like a buffered file stream (python's built-in class, TextIOWrapper
),
Plus, I am trying to add some more features(method) on it.
It would look similar to:
class ReadFile:
def __init__(self):
self._i = 0
def do_magic(self, file):
# ...
io = open(file)
return io
if __name__ == "__main__":
import pandas as pd
rf = ReadFile()
a = rf.do_magic("./data.csv")
data = pd.read_csv(a) # this should work
# a.desired_feature() # I want this as well
My first try was make a child class of TextIOWrapper
and casting.
class _TextIOWrapper(io.TextIOWrapper):
pass
# ...
def do_magic(self, file):
# ...
io = open(file)
io.__class__ = _TextIOWrapper
return io
And it gives me an TypeError
:
Traceback (most recent call last):
File "d.py", line 56, in <module>
a = rf.do_magic("./data.csv")
File "d.py", line 45, in do_magic
io.__class__ = _TextIOWrapper
TypeError: __class__ assignment only supported for heap types or ModuleType subclasses
My second try was adding the feature(method) on the built-in.
def add_method(cls):
def decorator(func):
@wraps(func)
def wrapper(self, *args, **kwargs):
return func(*args, **kwargs)
setattr(cls, func.__name__, wrapper)
return func
return decorator
@add_method(io.TextIOWrapper)
def desired_feature(self):
return None
Which gives me another TypeError
:
Traceback (most recent call last):
File "d.py", line 26, in <module>
@add_method(io.TextIOWrapper)
File "d.py", line 21, in decorator
setattr(cls, func.__name__, wrapper)
TypeError: can't set attributes of built-in/extension type '_io.TextIOWrapper'
Is there any other workaround that could make desired_feature()
work?