I wish to extend Python socket.socket
with a new attribute (in particular, a queue.Queue
, but could be anything else). I am trying
to decide whether I should use inheritance or composition, but at some point both pose a
problem I am not sure how to solve:
A) If I use inheritance, with something like:
class MySocket(socket.socket):
def __init__(self, *args, **kwargs):
socket.socket.__init__(self, *args, **kwargs)
self.queue = queue.Queue()
then I have problems when I use operations like
connection, client_address = s.accept()
because the accept
method of sockets returns objects of type socket.socket
, and not of type MySocket
,
and I am not sure how to convert one into the other. If there is is a trivial OOP way to do this,
I do not know it.
B) The problem before is trivially solved if I used composition instead:
class MySocket(socket.socket):
def __init__(self, true_socket):
self.true_socket = true_socket
self.queue = queue.Queue()
I would simply implement something like
def accept(self, *args, **kwargs):
con, cli = socket.socket.accept(self, *args, **kwargs)
return self.__class__(con), cli
But then I have another problem. When I need to do
readable, writable, exceptional = select.select(inputs, outputs, inputs)
select
works for socket.socket
. With the A) version I would expect this to work just as is,
but with composition, now that MySockets
are not instances of socket.socket
, select
is broken.
So, what is the best, pythonistic approach for this?
EDIT: I forgot to say that the first thing I tried was to add the attribute directly to instances of `socket.socket':
s = socket.socket(...)
s.queue = queue.Queue()
but I got an exception saying the attribute is unknown for 'socket.socket'.
socket.socket
uses__slots__
, which is why you can't add attributes. This also prevents you from doing something likes.__class__ = MySocket
... too bad. – Bacteriology