[Python-es] determinar cual clase ha sido declarada primero

Chema Cortes pych3m4 en gmail.com
Vie Ago 23 13:34:31 CEST 2013


El día 23 de agosto de 2013 12:02, Chema Cortes <pych3m4 en gmail.com> escribió:
> El día 22 de agosto de 2013 02:59, Juan BC <jbc.develop en gmail.com> escribió:
>> Estoy haciendo un pequeño script que recibe otro script por parametro
>> (osea un plugin) y lo que necesito es ordenar las clases dentro de el
>> plugin en el orden que fueron declaradas:
>>
>> en un ejemplo trivial seria algo asi:
>>
>> # plugin.py
>>
>> class B(object): pass
>> class A(object): pass
>>
>> # manager.py
>>
>> import plugin
>>
>> classes  = [k, v for k,v in vars(plugin).items()]
>> classes.sort(<CODIGO PARA ORDENAR B antes que A>)
>
> No es buena idea ésto que quieres hacer. Por ejemplo, ¿dónde dirías
> que se "declaran" las clases si hago ésto?:
>
>   from plugin import *
>
> ¿Y si me da por hacer cosas como estas?
>
>   class A: pass
>
>   B = A
>
>   class A: pass
>
> Hay dos clases, pero en verdad he redeclarado 'A'.
>
> Por lo que parece, estás creando una especie de API para creación de
> plugins y te gustaría obtener el orden de los plugins tal y como son
> declarados. Una solución sería usando metaclases tal como te ha
> sugerido Olemis Lang. Pero las metaclases son algo complejas de
> manejar y es posible evitar su uso en muchos casos desde que existen
> los decoradores de clase.
>
> Por ejemplo, puedes hacer lo siguiente:
>
> class Plugin(object):
>
>     def __init__(self):
>         self.plugins = {}
>
>     def register(self, cls):
>
>         if cls.__module__ not in self.plugins:
>             self.plugins[cls.__module__] = []
>
>         self.plugins[cls.__module__].append(cls.__name__)

Un pequeño fallo: para que funcione bien, el decorador debe devolver la clase

    def register(self, cls):

        if cls.__module__ not in self.plugins:
            self.plugins[cls.__module__] = []

        self.plugins[cls.__module__].append(cls.__name__)

        return cls

>
> plugin=Plugin()
>
> Y pedir a tus usuarios que "registren" sus plugins:
>
> @plugin.register
> class A(object):
>     pass
>
> @plugin.register
> class B(object):
>     pass
>
> Si quieres más control, puedes crear decoradores con argumentos, por
> ejemplo para pasar el nombre completo del plugin o el autor.
>
>
> --
> Hyperreals *R  "Quarks, bits y otras criaturas infinitesimales":
> http://ch3m4.org/blog
> Buscador Python Hispano: http://ch3m4.org/python-es



-- 
Hyperreals *R  "Quarks, bits y otras criaturas infinitesimales":
http://ch3m4.org/blog
Buscador Python Hispano: http://ch3m4.org/python-es


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