Seleccionar la clase a instanciar en tiempo de ejecucion

pachi en mmn-arquitectos.com pachi en mmn-arquitectos.com
Dom Feb 13 22:17:44 CET 2005


> Hola amigos listeros,
>
> necesito instanciar un objeto de una clase que no conoceré hasta tiempo de
> ejecución, y no quiero hacerlo mediante una cadena de if-then, ya que
> dispondré en tiempo de ejecución del nombre exacto de la clase a
> instanciar
> (me viene de un fichero XML). Sospecho que en Python debe haber una manera
> de hacer esto en "dos teclazos", pero como soy novatillo, pues no se me
> ocurre.
> ¿Alguien puede echarme una mano?

Tienes problemas de polimorfismo, jeje...
Dependiendo de cómo tengas que instanciar los objetos y cómo sean sus
constructores yo usaría una solución alternativa al switch mediante
diccionarios (dictionary dispatch). En términos más abstractos lo que
implementarás es un patrón Método de Fábrica (Factory method).

El primero puedes verlo implementado en el módulo pickle y comentado aquí:
http://c2.com/cgi/wiki?PythonIdioms
En este caso usarías el nombre del objeto que recibes en el XML como clave
para obtener un descriptor al constructor correspondiente.

El segundo (Factory Method) está comentado en
http://c2.com/cgi/wiki?FactoryMethodPattern y con más detalle en
http://gsraj.tripod.com/design/creational/factory/factory.html

Entre ambas tienes muchas soluciones y aquí va un ejemplito de juguete:
-------------------

def BuildC01(*buildparams):
    return C01(*buildparams)

def BuildC02(*buildparams):
    return C02(*buildparams)

class C01:
    def __init__(self, *buildparams):
        self.total = 0
        for param in buildparams:
            self.total += param

class C02:
    def __init__(self, *buildparams):
        self.total = 0
        for param in buildparams:
            self.total += param**2

Crea = {"C01" : BuildC01,
        "C02" : BuildC02}
params = (1, 2, 3)

nuevaClase01 = Crea["C01"](*params)
print nuevaClase01, nuevaClase01.total

nuevaClase02 = Crea["C02"](*params)
print nuevaClase02, nuevaClase02.total

----------------
que genera:

>>>
    <__main__.C01 instance at 0xb671b80c> 6
    <__main__.C02 instance at 0xb671b82c> 14
>>>

--
Pachi




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