我希望使用新属性(特别是socket.socket
扩展Python queue.Queue
,但可能是其他任何内容)。我在尝试
决定我是否应该使用继承或组合,但在某些时候两者都构成一个
问题我不知道如何解决:
A)如果我使用继承,例如:
class MySocket(socket.socket):
def __init__(self, *args, **kwargs):
socket.socket.__init__(self, *args, **kwargs)
self.queue = queue.Queue()
然后当我使用像
这样的操作时,我遇到了问题connection, client_address = s.accept()
因为套接字的accept
方法返回socket.socket
类型的对象,而不是MySocket
类型的对象,
我不知道如何将一个转换为另一个。如果有一个简单的OOP方式来做到这一点,
我不知道。
B)如果我改用组合物,那么以前的问题就会得到解决:
class MySocket(socket.socket):
def __init__(self, true_socket):
self.true_socket = true_socket
self.queue = queue.Queue()
我只想实现像
这样的东西def accept(self, *args, **kwargs):
con, cli = socket.socket.accept(self, *args, **kwargs)
return self.__class__(con), cli
但后来我又遇到了另一个问题。当我需要做的时候
readable, writable, exceptional = select.select(inputs, outputs, inputs)
select
适用于socket.socket
。使用A)版本,我希望它能够正常工作,
但是由于合成,现在MySockets
不是socket.socket
的实例,select
已被破坏。
那么,对此最好的蟒蛇方法是什么?
编辑:我忘了说我尝试的第一件事就是直接将属性添加到`socket.socket'的实例中:
s = socket.socket(...)
s.queue = queue.Queue()
但我得到一个例外,说'socket.socket'属性未知。
答案 0 :(得分:3)
您可以根据Lib/socket.py
中的socket.socket.dup()
使用以下内容:
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
您现在可以使用构造函数创建新的MySocket
,或使用MySocket.copy()
从现有MySocket
创建socket.socket
。请注意,在大多数情况下,您应该在创建副本后关闭原始套接字。
答案 1 :(得分:-1)
也许您应该尝试使用super
class NewSocket(socket.socket):
def __init__(self):
super(NewSocket, self).__init__()