[Python-es] búsqueda automática de clases en un paquete

Jose Caballero jcaballero.hep en gmail.com
Mar Oct 26 22:55:08 CEST 2010


El 13 de octubre de 2010 07:42, Juan Ignacio <euribates en gmail.com> escribió:

> ¿tendría que mantener a mano ese diccionario o hay forma de hacer que se
>> cree automáticamente?
>>
>> La idea es que se cree y gestione automaticamente, claro. He estado
> mirando las Metaclases  (que es un concepto donde estoy bastante perdido,
> pero sigo luchando) y se podría hacer algo así::
>
> -[ Cortar por aqui ]---------------------------------------
> class Base(type):
>     Catalogo = {}
>
>     def __new__(cls, name, bases, dct):
>         new_class = type.__new__(cls, name, bases, dct)
>         Base.Catalogo[name] = new_class
>         return new_class
>
> def instance_object_of_class(class_name, *args):
>     return Base.Catalogo[class_name](*args)
>
> class A1():
>     __metaclass__ = Base
>     def __str__(self): return 'Soy de la clase A1'
>
> class A2():
>     __metaclass__ = Base
>     def __str__(self): return 'Soy de la clase A2'
>
> class B1():
>     __metaclass__ = Base
>     def __str__(self): return 'Soy de la clase B1'
>
> class B2():
>     __metaclass__ = Base
>
>     def __init__(self, value):
>         self.value = value
>
>     def __str__(self): return 'Soy de la clase B2, value vale %s' %
> self.value
> -[ Cortar por aqui ]---------------------------------------
>
> Por ejemplo:
>
> >>> a1 = instance_object_of_class('A1')
> >>> print a1
> Soy de la clase A1
>
> >>> a2 = instance_object_of_class('A2')
> >>> print a2
> Soy de la clase A2
>
> >>> b1 = instance_object_of_class('B1')
> >>> print b1
> Soy de la clase B1
>
> >>> b2 = instance_object_of_class('B2', 23)
> >>> print b2
> Soy de la clase B2, value vale 23
>
> Lo unico que habria que hacer es incluir la referencia a la metaclase
> "Base" con la variable mágica __metaclass__ en la declaración de cada clase.
> Habría que codificar también un mensaje de error
> por si se intentar definir dos clases con el mismo nombre, ahora mismo la
> mas nueva machacaría a la
> mas antigua.
>
>

Hola,

contesto con varias semanas de retraso, pero es que hasta ahora no he podido
probar el código.

Más o menos funciona como quiero. La única diferencia entre mi caso real y
el ejemplo propuesto es que en mi caso las clases (A1, A2, B1, B2...) están
repartidas en distintos módulos. Y la clase Base también está en un módulo
diferente.

Con una variación del ejemplo propuesto ya me he ahorrado el tener que hacer
el check original

        if hasattr(mod1, name):
                return getattr(mod1, name)()

para cada una de las clases. Es todo un avance.  Muchas gracias por la
ayuda.

La única parte que aún tengo que hacer a mano es los imports de los módulos
donde están las clases. Y añadir un import nuevo si en algún momento se crea
un nuevo módulo.
Estoy jugando un poco con la combinación os.listdir() e __import__() como
alguien recomendó en este mismo hilo. Aún no consigo que cuadre bien, se
hace un lío con los directorios y tal, pero creo que antes o después
encontraré la solución.

Muchas gracias por todo.

Saludos,
Jose
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://mail.python.org/pipermail/python-es/attachments/20101026/c8830a82/attachment.html>


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