2009-11-22 14 views

Respuesta

34

Los decoradores son mucho, mucho más simples y más limitados, y por lo tanto deben preferirse siempre que el efecto deseado se pueda lograr con una metaclass o un decorador de clase.

Cualquier cosa que pueda hacer con un decorador de clases, puede hacerlo con una metaclass personalizada (solo aplique la funcionalidad de la "función decoradora", es decir, la que toma un objeto de clase y lo modifica, en el curso de la metaclass __new__ o __init__ que hacen que el objeto de clase! -).

Hay muchas cosas que puede hacer en una metaclass personalizada pero no en un decorador (a menos que el decorador genere internamente y aplique una metaclase personalizada, por supuesto, pero eso es hacer trampa; -) ... e incluso entonces, en Python 3, hay cosas que solo puedes hacer con una metaclase personalizada, no después del hecho ... pero ese es un sub-nicho muy avanzado de tu pregunta, así que déjame dar ejemplos más simples).

Por ejemplo, supongamos que desea hacer un objeto de clase X tal que print X (o en Python 3 print(X) por supuesto ;-) muestra peekaboo!. No puede hacer eso sin una metaclass personalizada, porque la anulación de la metaclase de __str__ es el actor crucial aquí, es decir, necesita un def __str__(cls): return "peekaboo!" en la metaclase personalizada de la clase X.

Lo mismo se aplica a todos los métodos mágicos, es decir, a todo tipo de operaciones aplicadas al objeto de clase en sí (a diferencia de, aplicadas a sus instancias , que utilizan métodos mágicos como se define en la clase - las operaciones en el objeto de clase en sí usan métodos mágicos como se define en la metaclase).

+0

respuesta interesante de eminent fellow countryman =) – gpilotino

+0

Hola gino, siempre especialmente contento de ayudar a un compatriota, por supuesto ;-). –

+6

Bueno ... han pasado 4 años y encontré esta pregunta en google. Solo quiero hacer una nota sobre tu ejemplo. He definido un decorador 'foo (cls)' que tiene 2 enunciados: 'cls .__ str__ = lambda self:" peekaboo! "' Y justo después de eso 'return cls', y realmente funcionó - He configurado' __str__' método de alguna clase con el decorador en lugar de una metaclass complicada ... Solo quería notar esto, y tal vez obtener algún comentario para saber si me estoy perdiendo algo. – rboy