I'm writing a high level wrapper around the Python socket.socket
object. Specifically, I want to do this for IPv4 TCP sockets (though it would be useful to be able to expand the library later with other families / types). As you may know, the socket module defines these as socket.AF_INET
and socket.SOCK_STREAM
. Is it a good idea to 'copy' these constants and make them constant class attributes, i.e.:
import socket
class IPv4TCPSocket(socket):
FAMILY = socket.AF_INET
TYPE = socket.SOCK_STREAM
def __init__(self):
...
Or should I refer to them directly? I get this may seem like a weird question since they're already constants in the socket
module, but referring to them by <libname>.socket.AF_INET
may be a bit awkward. Any thoughts on this?
As an alternative I just leave out the class attributes and initialize like this:
super().__init__(family=socket.AF_INET, type=socket.SOCK_STREAM)
This entirely leaves out a reference to the socket family and type, which I guess isn't a problem, except if someone else needs to create a custom socket (or derive one from IPv4TCPSocket
):
from <name> import IPv4TCPSocket as sock
print("Creating a new socket with family {} and type {}!".format(sock.FAMILY, sock.TYPE))
As opposed to
import <libname>
print("Creating a new socket with family {} and type {}!".format(<libname>.socket.AF_INET, <libname>.socket.SOCK_STREAM))
It's slightly more work and doesn't feel like an intuitive public interface to me. And hey, I may just be turning this into a way bigger problem than it really is, but I do that a lot :)
Second edit: new thoughts on the matter. After reading James' comment I found out (again, duh!) that socket.socket.type
and socket.socket.family
exist, which return the socket instance's type and family respectively. So, since I want to separate class behavior on a type & family basis, I may not subclass socket
at all. The question remains the same, however, since each of those wrapper instances need a private _socket
attribute of sorts as well.
The only real motive I can find to do this is to make the public interface easier to use. Or I might as well leave the attributes out altogether since the class name describes the socket. Decisions, decisions.
Answers are still very welcome, but I've decided to remove the constants and just let the class name signify its family and type.