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

Olemis Lang (Simelix) olemis+py en gmail.com
Mar Oct 26 23:17:51 CEST 2010


En general dos o tres sugerencias :

  - En unittest hay una función que carga un objeto instancia un
    object dado el camino absoluto. Allí se utiliza para cargar
    las test suites , test runners , ... que se prueban
  - En Trac PyDocPlugin se usa algo com esto para cargar
    cualquier objeto y mostrar su documentación en una
    interfaz web . Allí hay un ,étodo similar.
  - En setuptools existe una manera de hacer lo mismo.
    Para eso son los entry points . Si desea hacer algun mecanismo
    extensible y dinámico de plugins , los entry points son
    la respuesta, porque le permitirían incluso hacer lo que Ud
    desea hasta con clases de paquetes differentes. Por ejemplo
    esto lo usa Genshi para incorporar extractores de mensajes | texto
    personalizados que después se utilizan para i18n y l10n de apps Py
    (e.g. extraer texto de templates de Django o Cheetah o ...
    para i18n ;o). En este caso básicamente Ud implementa su
    función en su paquete y Genshi utiliza los entry points para
    añadirla al conjunto de funciones que utilizaría .

Creo que me iría por el último , el código es muy simple , lástima que
no lo recuerdo ... Oldy I am !!!

Todo esto se puede combinar con lo de las metaclases , claro ...
;o)

2010/10/26 Jose Caballero <jcaballero.hep en gmail.com>:
>
> 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
>
>
>
>
>
>
>
> _______________________________________________
> Python-es mailing list
> Python-es en python.org
> http://mail.python.org/mailman/listinfo/python-es
> FAQ: http://python-es-faq.wikidot.com/
>
>



-- 
Regards,

Olemis.

Blog ES: http://simelo-es.blogspot.com/
Blog EN: http://simelo-en.blogspot.com/

Featured article:


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