向现有套接字对象添加doRead()方法
有没有办法给一个已经存在的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 的源代码本身也是一个很好的参考,可以帮助你继续前进。