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

Chema Cortes pych3m4 en gmail.com
Vie Ago 23 19:27:04 CEST 2013


El día 23 de agosto de 2013 16:31, Olemis Lang <olemis en gmail.com> escribió:
> On 8/23/13, Chema Cortes <pych3m4 en gmail.com> wrote:
>> 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.
>>
>
> La elección entre meta-clases y decoradores de clases , en este caso ,
> puede ser a gusto de la persona en cuestión . De hecho en teoría Trac
> podría facilitar las dos variantes :
>
>   - metaclases para el sistema d plugins ComponentMeta (Component +
>     ComponentManager)
>   - decoradores de clases para declara las interfaces q
>     implementa una clase (i.e. implements)
>
> Nótese que en este caso la diferencia entre las dos variantes consiste
> en expresar intrínsecamente el comportamiento esperado de las clases
> (registrarse en orden en el cache global, añadir el comportamiento
> esperado del sistema d plugins e.g. implement ParametricSingleton
> pattern per ComponentManager, etc ...) vs el comportamiento específico
> d una clase en cuestión (registrarse en orden en el cache de la
> interface específica ...)
>
> Como se puede ver no son conceptos equivalentes . Las meta-clases
> participan en herencia , añaden comportamientos a los meta-objetos q
> representan las clases (clases) y sus instancias (objetos) ; además
> son tipos . Los decoradores son modificadores más puntuales ... quizás
> parecidos a la situación descriptores vs __getattr__
>
> El hecho de poner __metaclass__ en el cuerpo de la clase se puede
> solucionar haciendo la asignación en una clase base (e.g.
> trac.core.Component) y ya no es necesario repetirlo en las sub-clases
> . De hecho , en Trac + Bloodhound el hecho d tener ComponentMeta y
> todo el modelo meta es transparente ...

No he dicho que los decoradores fueran los sustitutos de las
metaclases, sino que pueden evitar tener que usarlas en determinadas
situaciones.

Las metaclases ofrecen la posibilidad de crear un modelo de datos
bastante consistente para el problema que necesites tratar; pero, en
mi opinion, tienen un verdadero problema con la herencia ya que las
metaclases no tienen herencia múltiple. Si necesitas combinar dos
modelos de datos distintos, cada uno con una metaclase, necesitarás
crear una supermetaclase común y modificar buena parte del código.

En cambio, los decoradores de clases se pueden encadenar uno tras otro
sin más preocupaciones.

Por otro lado, el valor de '__metaclass__' no tiene porque ser una
clase, ya que podría ser cualquier "callable", incluso una función, lo
que se asemejaría bastante a lo que hace un decorador. No veo que sea
tanta la diferencia entre uno y otro como lo pones, con la excepción
de que los decoradores son más explícitos. Y éso es bueno para según
qué cosas.



-- 
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