I want to create a file-like object to be passed to another module. I don't know if that other module will be calling read() or readline() or both. If I were to subclass say io.IOBase
and just implement read()
would that be sufficient, even if the client is calling readline()
?
Bonus question: if my class will be opened in text mode, what's the minimum I can implement to let the superclass handle the unicode decoding?
(This will be an input-only class.)
Meta: I know I could just write all the methods and see what actually gets called, but I'd like to be a bit "future proof" and write to the actual specs, instead of trying things to see if they work, and then having them break in the future someday.
CodePudding user response:
Empirically, implementing read
will be enough.
As for text mode, you'd want to just use TextIOWrapper
(which technically is meant to be used with a BufferedIOBase
, but it looks like things work with IOBase
too).
import io
class FooIO(io.IOBase):
def __init__(self, buffer):
self.buffer = buffer
self.pos = 0
def rewind(self):
self.pos = 0
def readable(self) -> bool:
return True
def read(self, size=-1):
if size == -1:
size = len(self.buffer) - self.pos
data = self.buffer[self.pos:self.pos size]
self.pos = size
return data
f = FooIO(b"hello\nworld\nthis\nis\na\ntest")
for x in range(7):
print(x, f.readline())
f.rewind()
tiow = io.TextIOWrapper(f)
for x in range(7):
print(x, repr(tiow.readline())))
prints out
0 b'hello\n'
1 b'world\n'
2 b'this\n'
3 b'is\n'
4 b'a\n'
5 b'test'
6 b''
0 'hello\n'
1 'world\n'
2 'this\n'
3 'is\n'
4 'a\n'
5 'test'
6 ''