class MyMeta(type):
def __new__(meta, cls, bases, attributes):
print 'MyMeta.__new__'
return type.__new__(meta, cls, bases, attributes)
def __init__(clsobj, cls, bases, attributes):
print 'MyMeta.__init__'
class MyClass(object):
__metaclass__ = MyMeta
foo = 'bar'
Une autre façon d'atteindre le même résultat:
cls = "MyClass"
bases =()
attributes = {'foo': 'bar'}
MyClass = MyMeta(cls, bases, attributes)
MyMeta
est un callable donc Python utilisera la méthode spéciale __call__
.
Python recherchera __call__
dans le type de MyMeta
(qui est type
dans notre cas)
« Pour les classes de type nouveau, les invocations implicites des méthodes spéciales sont seulement garanti pour fonctionner correctement si elle est définie sur un type d'objet, pas dans l'instance de l'objet dictionnaire »
MyClass = MyMeta(...)
est interprété comme:
my_meta_type = type(MyMeta)
MyClass = my_meta_type.__call__(MyMeta, cls, bases, attributes)
A l'intérieur du type.__call__()
j'imagine quelque chose comme ceci:
MyClass = MyMeta.__new__(MyMeta, cls, bases, attributes)
meta_class = MyClass.__metaclass__
meta_class.__init__(MyClass, cls, bases, attributes)
return MyClass
MyMeta.__new__()
décidera comment le MyClass
est construit:
type.__new__(meta, cls, bases, attributes)
va régler la métaclasse correcte (ce qui est MyMeta
) pour MyClass
type(cls, bases, attributes)
définira la métaclasse par défaut (qui est le type) pour MyClass
Mais c'est la question que je me pose: pourquoi 'type' ne retourne-t-il pas le bon type d'objet? Je sais que je dois utiliser la méthode '__new__' de la sous-classe, mais en quoi est-ce différent de l'utilisation de' type'? –
Comment le type est-il censé savoir par magie quel genre d'objet vous voulez qu'il fasse? –
bien, parce que je le dis. J'ai passé en nom, bases et dict. De quelle autre information ai-je besoin? –