使用新属性扩展 socket.socket
Extending socket.socket with a new attribute
我希望用新属性扩展 Python socket.socket
(特别是 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()
因为套接字 returns 类型 socket.socket
对象的 accept
方法,而不是 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
被破坏了。
那么,对此最好的 pythonistic 方法是什么?
编辑:我忘了说我尝试的第一件事是将属性直接添加到“socket.socket”的实例中:
s = socket.socket(...)
s.queue = queue.Queue()
但是我得到一个异常,说 'socket.socket' 的属性未知。
也许你应该尝试继承 super
class NewSocket(socket.socket):
def __init__(self):
super(NewSocket, self).__init__()
您可以使用以下内容,基于 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
您现在可以使用构造函数创建新的 MySocket
,或使用 MySocket.copy()
从现有的 socket.socket
创建 MySocket
。请注意,在大多数情况下,您应该在创建副本后关闭原始套接字。
我希望用新属性扩展 Python socket.socket
(特别是 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()
因为套接字 returns 类型 socket.socket
对象的 accept
方法,而不是 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
被破坏了。
那么,对此最好的 pythonistic 方法是什么?
编辑:我忘了说我尝试的第一件事是将属性直接添加到“socket.socket”的实例中:
s = socket.socket(...)
s.queue = queue.Queue()
但是我得到一个异常,说 'socket.socket' 的属性未知。
也许你应该尝试继承 super
class NewSocket(socket.socket):
def __init__(self):
super(NewSocket, self).__init__()
您可以使用以下内容,基于 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
您现在可以使用构造函数创建新的 MySocket
,或使用 MySocket.copy()
从现有的 socket.socket
创建 MySocket
。请注意,在大多数情况下,您应该在创建副本后关闭原始套接字。