Code: Alles auswählen
class mK(type):
print "Erzeuge MetaKlasse mK"
def __new__(cls, *args):
print "mK: __new__", type(cls)
return type.__new__(cls, *args)
def __init__(cls, *args):
print "mK: __init__", type(cls)
super(mK, cls).__init__(*args)
def __call__(cls, *args):
print "mK: __call__", type(cls)
return super(mK, cls).__call__(*args)
print mK
class K(object):
print "Erzeuge Klasse K, instantiiert von mK"
__metaclass__ = mK
def __new__(cls, *args):
print "K: __new__", type(cls)
return object.__new__(cls, *args)
def __init__(self):
print "K: __init__", type(self)
print K
print 'Erzeuge Instanz, ruft __call__ von mK auf'
instance = K()
print instance
Code: Alles auswählen
Erzeuge MetaKlasse mK
<class '__main__.mK'>
Erzeuge Klasse K, instantiiert von mK
mK: __new__ <type 'type'>
mK: __init__ <class '__main__.mK'>
<class '__main__.K'>
Erzeuge Instanz, ruft __call__ von mK auf
mK: __call__ <class '__main__.mK'>
K: __new__ <class '__main__.mK'>
K: __init__ <class '__main__.K'>
<__main__.K object at 0x80a494c>
Wegen cls vs. self: Ich nutze in Metaklassen eigentlich immer cls, korrekterweise müßte Metaklasse.__new__ eine andere Nomenklatur bekommen (hab Vorschläge wie 'mcls', 'meta' oder einfach 'm' gesehen).
Edit2:
Aus Sicht der Zielklasse ändert sich der Typ, wie man schön im Vgl. zu diesem Bsp. sehen kann:
Code: Alles auswählen
class Husten(object):
def __new__(cls, *args):
print "Husten: __new__", type(cls)
return object.__new__(cls, *args)
def __init__(self):
print "Husten: __init__", type(self)
Husten()
#--->
# Husten: __new__ <type 'type'>
# Husten: __init__ <class '__main__.Husten'>