Supposons que nous avons le type Noddy
tel que défini dans le tutoriel sur l'écriture de C modules d'extension pour Python. Maintenant, nous voulons créer un type dérivé, en écrasant seulement l' __new__()
méthode de Noddy
.
Actuellement, je utiliser l'approche suivante (vérification des erreurs supprimées pour des raisons de lisibilité):
PyTypeObject *BrownNoddyType =
(PyTypeObject *)PyType_Type.tp_alloc(&PyType_Type, 0);
BrownNoddyType->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
BrownNoddyType->tp_name = "noddy.BrownNoddy";
BrownNoddyType->tp_doc = "BrownNoddy objects";
BrownNoddyType->tp_base = &NoddyType;
BrownNoddyType->tp_new = BrownNoddy_new;
PyType_Ready(BrownNoddyType);
Cela fonctionne, mais je ne suis pas sûr si c'est La bonne Façon De le Faire. Je me serais attendu à ce que j'ai à régler l' Py_TPFLAGS_HEAPTYPE
drapeau, trop, parce que j'alloue dynamiquement le type d'objet sur le tas, mais cela conduit à une erreur dans l'interpréteur.
J'ai aussi pensé à appeler explicitement type()
l'aide PyObject_Call()
ou similaire, mais j'ai écarté l'idée. J'aurais besoin d'envelopper la fonction BrownNoddy_new()
dans une fonction Python objet et de créer un dictionnaire de mappage __new__
de cette fonction de l'objet, qui semble idiot.
Quelle est la meilleure façon d'aller à ce sujet? Mon approche correcte? Est-il une fonction d'interface j'ai raté?
Mise à jour
Il y a deux fils sur un sujet connexe sur le python-dev mailing list (1) (2). À partir de ces fils et de quelques expériences, je en déduire que je ne devrais pas réglé Py_TPFLAGS_HEAPTYPE
moins que le type est attribué par un appel à l' type()
. Il existe différentes recommandations dans ces fils si il est préférable d'allouer le type manuellement ou à l'appel d' type()
. Je serais heureux avec ce dernier, si seulement je savais ce que de la manière recommandée pour envelopper la fonction C qui est censé aller dans l' tp_new
logement. Pour les méthodes ordinaires de cette étape serait facile, je pourrais simplement utiliser PyDescr_NewMethod()
pour obtenir un adapté objet wrapper. Je ne sais pas comment créer un tel objet wrapper pour ma __new__()
méthode, bien que, peut-être que j'ai besoin de les sans papiers de la fonction PyCFunction_New()
pour créer un tel objet wrapper.