2009-03-06 11 views
6

he estado hackeando clases en Python como esto:metaclases Python

def hack(f,aClass) : 
    class MyClass(aClass) : 
    def f(self) : 
     f() 
    return MyClass 

A = hack(afunc,A) 

¿Qué se ve bastante limpio para mí. Toma una clase, A, crea una nueva clase derivada que tiene un método extra, llama a f y luego reasigna la nueva clase a A.

¿Cómo se diferencia esto de la piratería de metaclases en Python? ¿Cuáles son las ventajas de usar una metaclass sobre esto?

+0

¿Cuál es la razón para hacer esto? –

Respuesta

5

La definición de una clase en Python es una instancia de tipo (o una instancia de una subclase de tipo). En otras palabras, la definición de clase en sí es un objeto. Con las metaclases, tiene la capacidad de controlar la instancia de tipo que se convierte en la definición de clase.

Cuando se invoca una metaclase, tiene la capacidad de volver a escribir completamente la definición de la clase. Usted tiene acceso a todos los atributos propuestos de la clase, sus antepasados, etc. Más que inyectar un método o eliminar un método, puede modificar radicalmente el árbol de herencia, el tipo y casi cualquier otro aspecto. También puede encadenar metaclases juntos para una experiencia muy dinámica y totalmente intrincada.

Supongo que el beneficio real, sin embargo, es que el tipo de clase sigue siendo del tipo de la clase. En su ejemplo, escribiendo:

a_inst = A() 
type(a_inst) 

mostrará que es una instancia de MyClass. Sí, isinstance(a_inst, aClass) devolvería True, pero ha introducido una subclase, en lugar de una clase dinámica redefinida. La distinción allí es probablemente la clave.

Como señala rjh, la clase interna anónima también tiene implicaciones de rendimiento y extensibilidad. Una metaclase se procesa solo una vez, y el momento en que se define la clase, y nunca más. Los usuarios de su API también pueden ampliar su metaclase porque no está encerrada dentro de una función, por lo que gana un cierto grado de extensibilidad.

Este poco viejo artículo en realidad tiene una buena explicación que compara exactamente el enfoque "función de la decoración" que utilizó en el ejemplo con metaclases, y muestra la historia de la evolución del pitón metaclase en ese contexto: http://www.ibm.com/developerworks/linux/library/l-pymeta.html

1

También puede usar el type llamativo.

def hack(f, aClass): 
    newfunc = lambda self: f() 
    return type('MyClass', (aClass,), {'f': newfunc}) 

me parece type usando la manera más fácil de entrar en el mundo metaclase.

Cuestiones relacionadas