Binding de las variables libres de funciones
Arnau Sanchez
pyarnau en gmail.com
Vie Nov 7 11:31:16 CET 2008
German Kruszewski escribió:
> La manera de hacerlo que se me ocurrió fue la siguiente:
> class C:
> def __init__(self):
> for i in range(1,3):
> def f():
> print "Esta es la funcion %i" % i
> setattr(self, 'f' + str(i), f)
>
> c = C()
> c.f1()
> c.f2()
Antes de nada, apuntar que con eso estás añadiendo una función a la instancia,
no un método, que muy probablemente es lo que necesites. En Python esto último
se suele hacer con new.instancemethod(). Cierto es que "self" queda en la
clausura de "f" y por tanto puedes acceder igualmente a la instancia, pero
parece más lógico añadirlo explícitamente como método.
> Sin embargo, como mencioné antes, no puedo cambiar la aridad de la función.
> ¿Alguien sabe cómo podría solucionar el problema de generar automáticamente
> estas funciones sin agregar parámetros extra?
Lo estándar en estos casos es recubrir la función en cuestión con otra función
que cargue con los parámetros que no queremos. Asumiendo que, según lo comentado
antes, lo que pretendemos es añadir un método, el código podría quedar:
import new
class C:
def __init__(self):
self.k = "k"
for i in range(1, 3):
def f0(i=i):
def f(self):
print "funcion:", i, self.k
return new.instancemethod(f, self)
setattr(self, 'f' + str(i), f0())
Añado un acceso a una variable de instancia (k) para comprobar que es
efectivamente es accesible desde las funciones que creamos al vuelo.
En este punto parece lógico abstraer un poco el código, por una parte las líneas
que añaden el método y por otra la propia función de generación de "f". Podría
quedar así:
def add_method(instance, function, name):
method = new.instancemethod(function, instance)
setattr(instance, name, method)
class C:
def _add_f(self, i):
def f(self):
print "funcion:", i, self.k
add_method(self, f, 'f' + str(i))
def __init__(self):
self.k = 1
for i in range(1, 3):
self._add_f(i)
¿Funciona esto como esperas?
arnau
--
Web: http://www.arnau-sanchez.com
_______________________________________________
Lista de correo Python-es
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes
Más información sobre la lista de distribución Python-es