Home > Net >  Minimal implementation of a "file-like" object?
Minimal implementation of a "file-like" object?

Time:01-09

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 ''
  • Related