Bla*_*Kow 5 c++ python cpython python-extensions
我正在为 python 创建一个 C++ 扩展。parent它创建一个包含子模块的模块child。有child一个方法hello()。如果我把它称为
import parent
parent.child.hello()
> 'Hi, World!'
Run Code Online (Sandbox Code Playgroud)
如果我尝试导入我的函数,它会失败
import parent
from parent.child import hello
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> ModuleNotFoundError: No module named 'parent.child'; 'parent' is not a package
parent.child
> <module 'child'>
Run Code Online (Sandbox Code Playgroud)
这是我的代码 setup.py
from setuptools import Extension, setup
# Define the extension module
extension_mod = Extension('parent',
sources=['custom.cc'])
# Define the setup parameters
setup(name='parent',
version='1.0',
description='A C++ extension module for Python.',
ext_modules=[extension_mod],
)
Run Code Online (Sandbox Code Playgroud)
和我的custom.cc
#include <Python.h>
#include <string>
std::string hello() {
return "Hi, World!";
}
static PyObject* hello_world(PyObject* self, PyObject* args) {
return PyUnicode_FromString(hello().c_str());
}
static PyMethodDef ParentMethods[] = {
{nullptr, nullptr, 0, nullptr}
};
static PyMethodDef ChildMethods[] = {
{"hello", hello_world, METH_NOARGS, ""},
{nullptr, nullptr, 0, nullptr}
};
static PyModuleDef ChildModule = {
PyModuleDef_HEAD_INIT,
"child",
"A submodule of the parent module.",
-1,
ChildMethods,
nullptr,
nullptr,
nullptr,
nullptr
};
static PyModuleDef ParentModule = {
PyModuleDef_HEAD_INIT,
"parent",
"A C++ extension module for Python.",
-1,
ParentMethods,
nullptr,
nullptr,
nullptr,
nullptr
};
PyMODINIT_FUNC PyInit_parent(void) {
PyObject* parent_module = PyModule_Create(&ParentModule);
if (!parent_module) {
return nullptr;
}
PyObject* child_module = PyModule_Create(&ChildModule);
if (!child_module) {
Py_DECREF(parent_module);
return nullptr;
}
PyModule_AddObject(parent_module, "child", child_module);
return parent_module;
}
Run Code Online (Sandbox Code Playgroud)
我安装并构建了python setup.py build install.
那么,如何确保我的包裹parent是包裹呢?
我的代码是一个玩具示例,但我实际上希望在 C++ 级别定义两个模块。我不想将它们分成几个模块 - 因为它们共享一些 C++ 代码。
我希望有类似于此答案的方法Python扩展与多个模块
从扩展内部执行此操作是模拟导入系统识别为包的模块的行为的“简单”问题。(根据上下文,提供一个从外部执行相同操作的导入钩子可能会更好。)只需要进行一些更改:
"parent.child"。parent一个包:
PyModule_AddObject(parent_module, "__path__", PyList_New(0));
PyModule_AddStringConstant(parent_module, "__package__", "parent");
Run Code Online (Sandbox Code Playgroud)
child的成员:
PyModule_AddStringConstant(child_module, "__package__", "parent");
Run Code Online (Sandbox Code Playgroud)
sys.modules如果执行了导入,则按照 Python 的方式
进行更新:PyDict_SetItemString(PyImport_GetModuleDict(), "parent.child", child_module);
Run Code Online (Sandbox Code Playgroud)
当然,其中一些调用可能会失败;请注意,如果PyModule_AddObject失败,您必须删除对正在添加的对象的引用(为了清楚起见,我在这里没有这样做)。
| 归档时间: |
|
| 查看次数: |
1026 次 |
| 最近记录: |