当模块具有子模块时,如何为 python 3.x 制作 C 扩展?例如,我有一个名为 pet.c 的文件:
#include <Python.h>
PyObject* CatMeow(PyObject* self) {
return PyUnicode_FromString( ">*<" );
}
static PyMethodDef CatFunctions[] = {
{(char*) "meow", (PyCFunction) CatMeow, METH_NOARGS, NULL},
{NULL, NULL, 0, NULL}
};
static PyModuleDef CatDef = {
PyModuleDef_HEAD_INIT, "cat", "cat ext", -1, CatFunctions,
NULL, NULL, NULL, NULL
};
PyMODINIT_FUNC PyInit_cat(void) {
return PyModule_Create(&CatDef);
}
static PyModuleDef PetDef = {
PyModuleDef_HEAD_INIT, "pet", "pet ext", -1, NULL,
NULL, NULL, NULL, NULL
};
PyMODINIT_FUNC PyInit_pet(void) {
PyObject* p = PyModule_Create(&PetDef);
PyObject* c = PyInit_cat();
Py_INCREF(c);
PyModule_AddObject( p, "cat", c );
return p;
}
当我使用以下 setup.py 构建它时:
from distutils.core import setup, Extension
setup(
name='pet',
version='0.0',
ext_modules=[Extension('pet', ['pet.c'])]
)
我可以看到
>>> import pet
>>> pet.cat.meow()
'>*<'
或者
>>> from pet import cat
>>> cat.meow()
'>*<'
这是预期的,但是当我尝试时
>>> from pet.cat import meow
我有一个 ModuleNotFoundError 说...没有名为“pet.cat”的模块;'pet' 不是一个包,如果我尝试
>>> from pet import cat
>>> from cat import meow
我有一个 ModuleNotFoundError 说...没有名为“猫”的模块。但是如果我检查猫的类型
>>> type(cat)
<class 'module'>
它说它是一个模块。
我该如何进行这项工作?将模块对象添加到另一个在 python 2.7 中运行良好的模块。由于绝对导入风格,它不应该在 python3 中工作吗?或者我是否必须使用 PEP 489 中描述的多阶段初始化?