假设我们具有在编写用于Python的C扩展模块Noddy
的教程中定义的类型。现在我们要创建一个派生类型,仅覆盖的__new__()
方法Noddy
。
当前,我使用以下方法(去除了可读性的错误检查):
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);
这可行,但是我不确定这是否是正确的方法。我本来也希望设置Py_TPFLAGS_HEAPTYPE
标志,因为我在堆上动态分配了类型对象,但这样做会导致解释器出现段错误。
我还考虑过显式调用 type()
usingPyObject_Call()
或类似方法,但我放弃了这个想法。我需要将函数包装BrownNoddy_new()
在Python函数对象中,并创建一个映射__new__
到该函数对象的字典,这似乎很愚蠢。
最好的方法是什么?我的方法正确吗?我错过了接口功能吗?
更新资料
在python-dev邮件列表(1) (2)上,有两个主题相关的主题。从这些线程和一些实验中,我得出结论,Py_TPFLAGS_HEAPTYPE
除非类型是通过调用分配的,否则不应设置type()
。在这些线程中有不同的建议,无论是手动分配类型还是调用类型更好type()
。如果只有我知道包装应该放在tp_new
插槽中的C函数的推荐方式是什么,我会对后者感到满意。对于常规方法,此步骤很容易-我可以使用它PyDescr_NewMethod()
来获取合适的包装对象。我不知道如何为我的__new__()
方法创建这样的包装对象,也许我需要未记录的函数PyCFunction_New()
来创建这样的包装对象。