向现有套接字对象添加doRead()方法

1 投票
1 回答
539 浏览
提问于 2025-04-16 06:33

有没有办法给一个已经存在的socket对象添加一个doRead()方法呢?

这个socket需要一个doRead方法,这样才能通过addWriter方法传递给twisted的反应器(reactor)。

我试过使用新模块的实例方法,但好像不太管用……

>>> c
<socket._socketobject object at 0x7fcb03cc8b40>
>>> c.doRead = new.instancemethod(doRead, c, socket._socketobject)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: '_socketobject' object has no attribute 'doRead'

1 个回答

2

这里出问题的不是 new.instancemethod,而是你有一个 socket._socketobject,这是一个扩展类型的实例,它没有 __dict__,所以不能随便添加新的属性。

让一种对象看起来像另一种对象的常见方法是使用“包装”。你可以创建一个新类,这个类包含你想要的所有方法,并且持有对你的 socket 的引用。例如:

class Connection:
    def __init__(self, socket, protocol):
        self.socket = socket
        self.protocol = protocol

    def doRead(self):
        try:
            data = self.socket.recv(self.bufferSize)
        except socket.error, se:
            if se.args[0] == EWOULDBLOCK:
                return
            else:
                return main.CONNECTION_LOST
        if not data:
            return main.CONNECTION_DONE
        return self.protocol.dataReceived(data)

这段代码直接来自 Twisted,当然,它正好解决了你想解决的问题。 :)

重新实现 Twisted 的核心部分可能是一个有用的练习,可以帮助你理解所有部分是如何工作和结合在一起的,但当你遇到困难时,Twisted 的源代码本身也是一个很好的参考,可以帮助你继续前进。

撰写回答