2010-11-04 8 views
1

Est-il possible d'ajouter une méthode doRead() à un objet socket existant?Ajout d'une méthode doRead() à un objet socket existant

la socket nécessite une méthode doRead pour pouvoir être passée au réacteur twisted via la méthode addWriter.

j'ai essayé d'utiliser la nouvelle méthode d'instance du module, mais il ne semble pas fonctionner ...

>>> 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' 

Répondre

2

Ce n'est pas new.instancemethod qui est ici défaut. C'est le fait que vous avez un socket._socketobject, une instance d'un type d'extension, qui n'a pas de __dict__ et ne peut donc pas recevoir de nouveaux attributs arbitraires.

La manière habituelle de faire ressembler un type d'objet à un autre type d'objet consiste à utiliser l'habillage. Créer une nouvelle classe qui a toutes les méthodes que vous voulez et obtient une référence à votre socket. Par exemple:

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) 

Ceci est copié directement à partir de Twisted, bien sûr - il est la solution exactement le problème que vous essayez de résoudre. :)

Ré-implémenter les tripes de Twisted pourrait être un exercice utile pour vous assurer que vous comprenez comment toutes les pièces fonctionnent et s'emboîtent, mais quand vous êtes coincé, la source Twisted elle-même fait une très bonne référence pour vous aider à ta façon.

+0

ouais, c'est exactement ce que j'ai fini par faire à la fin. Je pensais qu'il serait plus simple d'ajouter une méthode dans l'objet plutôt que de créer un wrapper, mais je suppose que dans ce cas, il ne peut pas être fait. J'ai effectivement regardé la source de la classe de connexion pendant un certain temps, mais je ne pouvais pas comprendre ce que le paramètre de protocole était, je suppose qu'il s'agit d'un objet de protocole de twisted.internet.protocol? – momo

+0

Oui, c'est ce que c'est. Et c'est là qu'il envoie les données qu'il lit réellement du réseau. –

Questions connexes