llamar una funcion con parametro (completa)

Joaquin Jose del Cerro Murciano jjdelcerro en cenoclap.es
Vie Ene 31 09:32:58 CET 2003


Si haces el "... command = self.nuevo_renglon(nro)...", lo que estas haciendo 
es asignarle al command el resultado de invocar a la funcion con el parametro 
"nro", que no es lo que se pretende. El command lo que ha de recibir es un 
"apuntador" a la funcion, no el resultado de su ejecucion, y eso se consigue 
referenciando a la funcion sin ponerle los parentesis, "... command = 
self.nuevo_renglon ...". Pero !ho! albricias, asi no le puedes pasar 
parametros.

Esto puedes solucionarlo de varias maneras:
1) la funcion "self.nuevo_renglon" es un metodo de una clase (por lo del 
self). Podrias dejar el parametro en el objeto y recojerlo cuando se invoque 
el metodo "nuevo_renglon":

def botonera(self,nro):
 ...
 self.nro = nro
 botones.add('Nuevo',command = self.nuevo_renglon)
 ...

def nuevo_renglon(self):
  nro = self.nro
  agrego_cosas.....

2) La opcion uno es valida cuando tienes una clase de por medio. Pero ¿ y si  
no tienes una clase de por medio ? Pues te montas una a modo wraper.

class MiFuncion(object):
  def __init__(self, callback, nro):
    self.callback = callback
    self.nro = nro

  def __call__(self):
    self.callback(nro)

def botonera(self,nro):
 ...
 botones.add('Nuevo',command = MiFuncion(self.nuevo_renglon,nro) )
 ...

def nuevo_renglon(self, nro):
  agrego_cosas.....

La cuestion es que una funcion es un objeto "callable", es decir que se puede 
invocar con "funcion()". Ahora bien si tu donde debe ir una funcion pones 
cualquier objeto que sea "callable" todo funcionara como si de una funcion se 
tratase. 
Un objeto es "callable" si la clase implementa el metodo "__call__", y cuando 
se invoque al objeto con "objeto()" se llamara al metodo __call__. Cha 
chan..., asi que lo que hacemos en la clase MiFuncion es hacerla callable. 
Ademas en el contructor de la clase le pasamos la funcion a la que debera 
llamar, y los parametros que tendra que pasarle, asi en el metodo __call__ 
sabremos a donde llamar y que argumentos pasarle.

Tanto para el caso 1 como el 2, esto funciona solo si lo que queremos es que 
cuando se invoque al evento el valor de nro sea el que tenia cuando se hizo 
la asignacion al command. Si no queremos esto, hay que añadir algo mas de 
codigo, por que en python no se pueden pasar variables por referencia.


Un saludo
Joaquin
CENOCLAP S.A.



El Mié 29 Ene 2003 19:58, Marcelo Abeldaño escribió:
> siguiendo con las consultas de novato:
>
> -------------------8<---------------------
> def botonera(self,nro):
>  ...
>  botones.add('Nuevo',command =
> self.nuevo_renglon(nro))
>  ...
>
> def nuevo_renglon(self,nro):
>  agrego_cosas.....
>  ...
> -------------------8<---------------------
>
> lo que pasa es lo siguiente, cuando llamo a
> command = self.nuevo_renglon
> sin parametros, funciona todo ok. El problema es que
> le tengo que pasar un parametro
> command = self.nuevo_renglon(nro)
> entonces me ejecuta la funcion al inicializar...
>
> desde ya gracias a todos por la ayuda
> Marcelo
>
>
> =====
> Perdimos trabajo, petroleo, industria, el campo, empresas, la salud, la
> justicia, educación y lo peor...... unos pocos nos robaron el futuro.....
> Ahora decime: POR QUE CARAJO MENEM SE MERECE TU VOTO?
> No dejes que le robe el futuro también nuestros hijos........
>
> Ahora podés usar Yahoo! Messenger desde tu celular. Aprendé cómo hacerlo en
> Yahoo! Móvil: http://ar.mobile.yahoo.com/sms.html
> _______________________________________________
> Python-es mailing list
> Python-es en aditel.org
> http://listas.aditel.org/listinfo.py/python-es

-- 
--------------------------------------
Joaquin Jose del Cerro Murciano

jjdelcerro en cenoclap.es




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