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'.
SOCK_STREAM. Provides sequenced, two-way byte streams with a transmission mechanism for stream data. This socket type transmits data on a reliable basis, in order, and with out-of-band capabilities. In the UNIX domain, the SOCK_STREAM socket type works like a pipe.
AF_INET is the Internet address family for IPv4. SOCK_STREAM is the socket type for TCP, the protocol that will be used to transport messages in the network. The . bind() method is used to associate the socket with a specific network interface and port number: # echo-server.py # ... with socket.
It means that your given host name ' ' is invalid (gai stands for getaddrinfo() ).
bind() − This method binds the address (hostname, port number) to the socket.
You can use the following, based on socket.socket.dup() in Lib/socket.py:
import _socket
class MySocket(socket.socket):
def __init__(self, *args, **kwargs):
super(MySocket, self).__init__(*args, **kwargs)
self.queue = queue.Queue
@classmethod
def copy(cls, sock):
fd = _socket.dup(sock.fileno())
copy = cls(sock.family, sock.type, sock.proto, fileno=fd)
copy.settimeout(sock.gettimeout())
return copy
You can now use the constructor to create new MySockets, or use MySocket.copy() to create a MySocket from an existing socket.socket. Note that in most cases you should close the original socket after creating the copy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With