[Python-es] RE: [Python-es] ¿Cierres en Python?

Esteban Manchado Velázquez zoso en demiurgo.org
Mie Ago 7 15:42:15 CEST 2002


Siento la duplicación del mensaje original, es que envié el correo desde otra
dirección y como no me llegaba el aviso de que el administrador lo estaba
mirando, decidí enviarlo de nuevo, pero con la dirección «de verdad».

On Wed, Aug 07, 2002 at 02:47:53PM +0200, Hernan Martinez Foffani wrote:
> si quien dispara el handler (supongo que algun metodo de jabber)
> tiene a mano el objeto self de Clase, bastaría con que registres
> en el handler el "unbound method" Clase.nuevoMensaje
> pero sospecho que no vas a tener referencia al objeto self, no?

   Exacto. Ése es precisamente el problema.

> ¿tiene que ser nuevoMensaje() un metodo de la clase?

   No necesariamente, pero tiene que tener alguna forma de saber cuál es el
objeto que registró la función de recepción de mensaje. La única solución que
se me ocurre para que una función tenga «consciencia» de un valor es que esa
función sea un método.... o usar un cierre.

> ¿cual es la interfaz de jabber.setMessageHandler()?

   La definición completa es

------------------------- 8< -------------------------
       def setMessageHandler(self, func, type='default'):
        """Sets a the callback func for recieving messages
           Mulitple callback functions can be set which are
           called in succession. A type attribute can also be
           optionally passed so the callback is only called when a
           message of this type is recieved.
           """

        self.msg_hdlrs.append({  type : func }) 
------------------------- >8 -------------------------


> si no es un metodo de Clase, pasarle eso solo te traerá problemas.
> 
> 
> hay una forma algo extraña de simular closures.  es sucia y
> limitada (no sirve si tenes que registrar mas de un handler)
> ejemplo (no probado):
> 
> class Clase:
>     def __init__(self):
>         # ...
>         self.jabber.setMessageHandler(self)
> 
>     def __call__(self, con, msg):
>         self.nuevoMensaje(con, msg)
> 
>     def nuevoMensaje(self, con, msg):
>         print "He recibido un nuevo mensaje con el texto %s" % msg

   Algo parecido se me había ocurrido, pero me hice un lío y no di con la
solución. Probando algo similar a lo que propones, da otro error en la
llamada, porque al objeto le falta el atributo «func_code». Supongo que debe
ser algo interno de las funciones.

   El caso es que mirando el paquete jabber.py he visto que el método que
hace las llamadas a las funciones registradas con setMessageHandler está
«preparada» para sobrecargarse. Me parece una forma un poco cutre de hacerlo
(habría preferido que la función fuera más genérica y me ahorrara tener que
sacar una clase derivada sólo para cambiar la forma de llamada y almacenar un
valor que necesito), pero qué se le va a hacer :-)

   Gracias, Hernán,

-- 
Esteban Manchado Velázquez <zoso*demiurgo*org> - http://www.demiurgo.org
No software patents in Europe! - freepatents.org - proinnova.hispalinux.es
Join Amnesty International - http://www.amnesty.org/actnow

   PD: Por cierto, ¿no se supone que añadieron cierres a Python 2.2? Yo uso
2.1, es sólo por curiosidad.


Más información sobre la lista de distribución Python-es