2009-03-06 7 views
6

Ich habe Klassen in Python wie das Hacking:Python metaclasses

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

A = hack(afunc,A) 

Was mir ziemlich sauber aussieht. Es braucht eine Klasse, A, erstellt eine neue Klasse, die davon abgeleitet ist, die eine zusätzliche Methode hat, ruft f auf und weist die neue Klasse dann wieder zu A.

Wie unterscheidet sich das vom Metaklassen-Hacken in Python? Was sind die Vorteile der Verwendung einer Metaklasse darüber?

+0

Was ist der Grund dafür? –

Antwort

5

Die Definition einer Klasse in Python ist eine Instanz des Typs (oder eine Instanz einer Unterklasse vom Typ). Mit anderen Worten, die Klassendefinition selbst ist ein Objekt. Mit Metaklassen können Sie die Typinstanz steuern, die zur Klassendefinition wird.

Wenn eine Metaklasse aufgerufen wird, können Sie die Klassendefinition vollständig neu schreiben. Sie haben Zugriff auf alle vorgeschlagenen Attribute der Klasse, ihrer Vorfahren usw. Mehr als nur das Einfügen einer Methode oder das Entfernen einer Methode können Sie den Vererbungsbaum, den Typ und so gut wie jeden anderen Aspekt radikal ändern. Sie können auch Metaklassen für eine sehr dynamische und völlig verworrene Erfahrung miteinander verknüpfen.

Ich nehme an, der wirkliche Vorteil ist, dass der Typ der Klasse der Typ der Klasse bleibt. In Ihrem Beispiel eingeben:

a_inst = A() 
type(a_inst) 

wird zeigen, dass es eine Instanz von MyClass ist. Ja, isinstance(a_inst, aClass) würde True zurückgeben, aber Sie haben eine Unterklasse anstelle einer dynamisch neu definierten Klasse eingeführt. Die Unterscheidung dort ist wahrscheinlich der Schlüssel.

Wie rjh darauf hinweist, hat die anonyme innere Klasse auch Auswirkungen auf die Leistung und die Erweiterbarkeit. Eine Metaklasse wird nur einmal verarbeitet, und der Moment, in dem die Klasse definiert ist, und nie wieder. Benutzer Ihrer API können auch Ihre Metaklasse erweitern, da sie nicht in einer Funktion enthalten ist, so dass Sie ein gewisses Maß an Erweiterbarkeit erhalten.

Dieser leicht alte Artikel hat eigentlich eine gute Erklärung, die genau die Funktion „Dekoration“ Ansatz, den Sie in dem Beispiel mit metaclasses verwendet wird, vergleicht und zeigt die Geschichte der Evolution metaclass Pythons in diesem Zusammenhang: http://www.ibm.com/developerworks/linux/library/l-pymeta.html

1

Sie können die type auch abrufbar verwenden.

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

Ich finde mit type der einfachste Weg in die Metaklasse Welt zu bekommen.