My client API encapsulates connections to the server in a class ServerConnection
that stores an asyncio.StreamReader/-Writer
pair. (For simplicity, I will not use yield from
or any other async technique in the code below because it doesn't matter for my question.)
Now, I wonder whether it's better to expose both streams as part of ServerConnection
's public interface than to introduce read()/write() methods to ServerConnection
which forward calls to the respective stream's methods. Example:
class ServerConnection:
def __init__(self, reader, writer):
self.reader = reader
self.writer = writer
vs.
class ServerConnection:
def __init__(self, reader, writer):
self._reader = reader
self._writer = writer
def read(self, size):
return self._reader.read(size)
def readline(self):
return self._reader.readline()
def write(self, data):
return self._writer.write(data)
def close(self):
return self._writer.close()
# …further proxy methods…
Pros/cons that I'm aware of so far:
Pros: ServerConnection
is definitely some kind of bidirectional stream so it'd make sense to have it inherit from a StreamRWPair
. Furthermore, it's much more convenient to use server_conn.read()
than server_conn.reader.read()
.
Cons: I would need to define a whole lot of proxy methods. (In my case, I actually use some kind of buffered reader that has additional methods like peek()
and so on.) So I thought about creating a base class StreamRWPair
similar to Python's io.BufferedRWPair
that my ServerConnection
can then inherit from. The Python implementation of the io
module, however, says the following about BufferedRWPair
in the comments:
XXX The usefulness of this (compared to having two separate IO objects) is questionable.
On top of that, my ServerConnection
class has several other methods and I'm afraid that, by proxying, I will clutter its attribute namespace and make its usage less obvious.