Sollte __metaclass__ nicht die Verwendung einer Metaklasse in Python erzwingen?
-
03-07-2019 - |
Frage
Ich habe versucht, über metaclasses in Python zu lernen. Ich erhalte die Hauptidee, aber ich kann nicht scheinen, um den Mechanismus zu aktivieren. Wie ich es verstehe, können Sie M angeben, die als Metaklasse sein, wenn durch das Setzen __metaclass__
zu M auf globale oder Klassenstufe eine Klasse K zu konstruieren. Um dies zu testen aus, schrieb ich das folgende Programm:
p = print
class M(type):
def __init__(*args):
type.__init__(*args)
print("The rain in Spain")
p(1)
class ClassMeta:
__metaclass__ = M
p(2)
__metaclass__ = M
class GlobalMeta: pass
p(3)
M('NotMeta2', (), {})
p(4)
Allerdings, wenn ich es laufen, bekomme ich die folgende Ausgabe:
C:\Documents and Settings\Daniel Wong\Desktop>python --version Python 3.0.1 C:\Documents and Settings\Daniel Wong\Desktop>python meta.py 1 2 3 The rain in Spain 4
Sollte ich nicht „Die regen in Spanien“ nach 1 und 2 sehen? Was ist denn hier los?
Lösung
In Python 3 (die Sie verwenden) metaclasses durch ein Schlüsselwort Parameter in der Klassendefinition angegeben werden:
class ClassMeta(metaclass=M):
pass
Die Angabe eine __metaclass__
Klasse Eigenschaft oder globale Variable ist alte Syntax von Python 2.x und nicht mehr unterstützt. Siehe auch "Was ist neu in Python 3" und PEP 2115 .
Andere Tipps
Das funktioniert, wie Sie in Python 2.6 (und früher), aber in 3.0 metaclasses angegeben anders erwarten:
class ArgMeta(metaclass=M): ...
Die Syntax von metaclasses hat geändert in Python 3.0. Das __metaclass__
Attribut ist nicht mehr besondere entweder in der Klasse noch Modulebene. Zu tun, was Sie zu tun versuchen, müssen Sie metaclass
als Schlüsselwort Argument der class
Anweisung angeben:
p = print
class M(type):
def __init__(*args):
type.__init__(*args)
print("The rain in Spain")
p(1)
class ClassMeta(metaclass=M): pass
Ausbeuten:
1
The rain in Spain
Wie man erwarten würde.