zey*_*cus 6 python sockets oop inheritance composition
我希望socket.socket使用新属性扩展Python (特别是a queue.Queue,但可能是其他任何东西).我试图决定是否应该使用继承或组合,但在某些时候两个都有问题,我不知道如何解决:
A)如果我使用继承,例如:
class MySocket(socket.socket):
def __init__(self, *args, **kwargs):
socket.socket.__init__(self, *args, **kwargs)
self.queue = queue.Queue()
Run Code Online (Sandbox Code Playgroud)
当我使用像这样的操作时,我遇到了问题
connection, client_address = s.accept()
Run Code Online (Sandbox Code Playgroud)
因为accept套接字的方法返回类型的对象socket.socket,而不是类型的对象MySocket,我不知道如何将一个转换为另一个.如果有一个简单的OOP方式来做到这一点,我不知道.
B)如果我使用组合代替,之前的问题很容易解决:
class MySocket(socket.socket):
def __init__(self, true_socket):
self.true_socket = true_socket
self.queue = queue.Queue()
Run Code Online (Sandbox Code Playgroud)
我会简单地实现类似的东西
def accept(self, *args, **kwargs):
con, cli = socket.socket.accept(self, *args, **kwargs)
return self.__class__(con), cli
Run Code Online (Sandbox Code Playgroud)
但后来我又遇到了另一个问题.当我需要做的时候
readable, writable, exceptional = select.select(inputs, outputs, inputs)
Run Code Online (Sandbox Code Playgroud)
select适用于socket.socket.随着A)版本,我希望它可以就像是工作,但组成,现在MySockets都没有的情况下socket.socket,select被打破了.
那么,什么是最好的,pythonistic方法呢?
编辑:我忘了说我尝试的第一件事是直接将属性添加到`socket.socket'的实例:
s = socket.socket(...)
s.queue = queue.Queue()
Run Code Online (Sandbox Code Playgroud)
但我得到一个例外,说'socket.socket'的属性是未知的.
您可以使用以下内容,基于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
Run Code Online (Sandbox Code Playgroud)
现在,您可以使用构造函数来创建新的MySocketS,或使用MySocket.copy()创建MySocket从现有的socket.socket。请注意,在大多数情况下,您应该在创建副本后关闭原始套接字。