使用新属性扩展socket.socket

时间:2017-07-20 06:58:02

标签: python sockets oop inheritance composition

我希望使用新属性(特别是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'属性未知。

2 个答案:

答案 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__()