【发布时间】:2011-12-25 08:54:02
【问题描述】:
假设我们有Noddy 中定义的tutorial on writing C extension modules for Python 类型。现在我们要创建一个派生类型,只覆盖Noddy 的__new__() 方法。
目前我使用以下方法(为了可读性而去除错误检查):
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 标志,因为我在堆上动态分配类型对象,但这样做会导致解释器中的段错误。
我还考虑过使用PyObject_Call() 或类似方法显式调用type(),但我放弃了这个想法。我需要将函数 BrownNoddy_new() 包装在 Python 函数对象中,并创建一个字典映射 __new__ 到该函数对象,这似乎很愚蠢。
解决此问题的最佳方法是什么?我的方法正确吗?有没有漏掉的界面功能?
更新
python-dev 邮件列表(1)(2) 上有两个相关主题的主题。从这些线程和一些实验中,我推断我不应该设置Py_TPFLAGS_HEAPTYPE,除非该类型是通过调用type() 分配的。这些线程中有不同的建议,无论是手动分配类型还是调用type() 更好。如果我知道包装应该放在 tp_new 插槽中的 C 函数的推荐方法是什么,我会对后者感到满意。对于常规方法,这一步很容易——我可以使用PyDescr_NewMethod() 来获取合适的包装对象。我不知道如何为我的__new__() 方法创建这样的包装对象——也许我需要未记录的函数PyCFunction_New() 来创建这样的包装对象。
【问题讨论】:
-
据我所知,这就是这样做的方法:(但我不确定。我认为是这样,因为覆盖 new 方法的要求很友好奇特的..
-
@CHENZhao:在我的用例中,基本类型是用虚拟成员函数包装 C++ 类。派生类型只需覆盖
__new__()即可分配不同的C++ 类。方法不需要被覆盖,因为它们调用了虚拟成员函数。请注意,我同时通过使用模板技术的完全不同的设计解决了这个问题。不过,最初的问题仍然存在。 -
如果你在这里找不到答案,也许你可以询问 python-dev 邮件列表,然后返回这里来回答
-
@XavierCombelle:python-dev 邮件列表旨在协调 Python 本身的开发。它不适用于提问的用户。
-
@SvenMarnach 其他可能性 python-list@python.org
标签: python derived-class python-2.x python-c-api