如何在Python C扩展模块中创建自定义类型的静态对象
实现方案
首先修正现有代码的类型不匹配问题,再完成实例字段填充和列表导出:
1. 修正自定义类型的成员定义
你当前Country结构体的name、capital是char*类型,但PyMemberDef中指定的T_OBJECT_EX对应PyObject*类型,二者不匹配会导致内存访问错误。我们调整为存储Python字符串对象,符合Python扩展的常规实现:
typedef struct { PyObject_HEAD PyObject *name; // 改为PyObject*存储Python字符串 PyObject *capital; } Country; static struct PyMemberDef CountryMembers[] = { {"name", T_OBJECT_EX, offsetof(Country, name), 0, "国家名称"}, {"capital", T_OBJECT_EX, offsetof(Country, capital), 0, "首都名称"}, {NULL} }; // 补充析构函数避免内存泄漏 static void Country_dealloc(Country* self) { Py_XDECREF(self->name); Py_XDECREF(self->capital); Py_TYPE(self)->tp_free((PyObject*)self); } static PyTypeObject CountryType = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "countries.Country", .tp_doc = "国家信息类型", .tp_basicsize = sizeof(Country), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_new = PyType_GenericNew, .tp_members = CountryMembers, .tp_dealloc = (destructor)Country_dealloc, // 注册析构函数 };
2. 实例化自定义类型并填充字段
创建实例后,可以直接通过结构体指针操作成员,执行效率更高:
// 模块初始化函数内的代码 // 1. 创建存储所有国家的列表 PyObject *countries_list = PyList_New(0); if (!countries_list) { return NULL; } // 2. 创建Country实例并填充字段 Country *afghanistan = (Country*)PyObject_CallObject((PyObject*)&CountryType, NULL); if (!afghanistan) { Py_DECREF(countries_list); return NULL; } // 填充字段:将C字符串转为Python Unicode对象赋值给结构体成员 afghanistan->name = PyUnicode_FromString("Afghanistan"); afghanistan->capital = PyUnicode_FromString("Kabul"); // 3. 将实例添加到国家列表 PyList_Append(countries_list, (PyObject*)afghanistan); // 列表已经持有实例引用,释放局部引用避免内存泄漏 Py_DECREF(afghanistan); // 可按照上述逻辑批量添加其他国家实例 // 4. 将国家列表注册为模块导出成员 PyModule_AddObject(local_module, "countries", countries_list);
3. 可选通用属性设置方案
如果你不想依赖结构体的内部定义,也可以用Python对象通用属性设置API实现字段填充,不需要强制转换结构体指针:
PyObject *afghanistan = PyObject_CallObject((PyObject*)&CountryType, NULL); PyObject_SetAttrString(afghanistan, "name", PyUnicode_FromString("Afghanistan")); PyObject_SetAttrString(afghanistan, "capital", PyUnicode_FromString("Kabul"));
这种方式更适合跨模块调用自定义类型的场景。
内容的提问来源于stack exchange,提问作者Jack M
相关产品推荐
相关产品推荐

