You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python嵌套包中C扩展模块无法导入问题求助

解决嵌套包中C扩展模块的ImportError问题

问题根源

你遇到的ImportError: cannot import name 'dummyext' from 'rootpack'本质是C扩展模块的初始化函数名称与模块的完整限定名不匹配,导致Python无法正确识别并注册该扩展模块到rootpack包下。

当C扩展模块属于嵌套包(如rootpack.dummyext)时,Python会寻找名为PyInit_<完整模块名>的初始化函数(其中点号替换为下划线,即PyInit_rootpack_dummyext),但你的原代码中初始化函数是PyInit_dummyext,与预期名称不符,因此导入失败。

修复步骤

1. 修改C扩展的初始化函数及模块定义

更新dummy.c中的两处关键内容:

  • 将模块定义的名称改为完整限定名"rootpack.dummyext"(确保模块的__name__正确)
  • 将初始化函数名从PyInit_dummyext改为PyInit_rootpack_dummyext

修改后的dummy.c代码:

#include <Python.h>
#include <numpy/arrayobject.h>

static PyObject* dummy_method(PyObject* self, PyObject* args)
{
    npy_int rows = 3;
    npy_int cols = 4;
    npy_intp dims[2] = {rows, cols};
    PyObject* arr_obj = PyArray_ZEROS(2, dims, NPY_INTP, 0);
    int* arr_data = PyArray_DATA(arr_obj);

    for(int i = 0; i < rows; ++i)
    {
        for(int j = 0; j < cols; ++j)
        {
            arr_data[i*cols + j] = i+j;
        }
    }
    return arr_obj;
}

static PyMethodDef dummyext_methods[] = {
    {"dummy_method", dummy_method, METH_VARARGS, "Returns a dummy array"},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef dummyext_module = {
    PyModuleDef_HEAD_INIT,
    "rootpack.dummyext",  // 改为完整模块名
    NULL,
    -1,
    dummyext_methods
};

PyMODINIT_FUNC PyInit_rootpack_dummyext(void)  // 匹配完整模块名的初始化函数
{
    PyObject* module = PyModule_Create(&dummyext_module);
    import_array();
    return module;
}

2. 调整setup.py配置(二选一即可)

方式一:不使用ext_package,直接指定完整模块名

保持原setup.py的ext_modules配置不变,仅确保Extension的名称是rootpack.dummyext:

import setuptools
import numpy

PACKAGE_NAME = 'rootpack'

setuptools.setup(
    name=PACKAGE_NAME,
    version="0.0.1",
    description="Testing extension module",
    packages=[PACKAGE_NAME],
    ext_modules = [
        setuptools.Extension(
            'rootpack.dummyext',
            ['ext/dummy.c'],
            extra_compile_args=["-std=c99"],
            include_dirs=[numpy.get_include()],
        ),
    ],
    install_requires=[
        'numpy',
    ],
)

方式二:使用ext_package简化模块名配置

启用ext_package参数,并将Extension的名称改为相对模块名dummyext,此时setuptools会自动为其添加rootpack前缀:

import setuptools
import numpy

PACKAGE_NAME = 'rootpack'

setuptools.setup(
    name=PACKAGE_NAME,
    version="0.0.1",
    description="Testing extension module",
    packages=[PACKAGE_NAME],
    ext_package=PACKAGE_NAME,  # 启用扩展包前缀
    ext_modules = [
        setuptools.Extension(
            'dummyext',  # 仅写相对模块名
            ['ext/dummy.c'],
            extra_compile_args=["-std=c99"],
            include_dirs=[numpy.get_include()],
        ),
    ],
    install_requires=[
        'numpy',
    ],
)

3. 测试注意事项

使用tox/cibuildwheel/pytest测试时,务必确保:

  • 测试环境中已正确安装构建后的包(而非直接运行源码目录)
  • tox配置中包含pip install .或pip install -e .步骤,保证模块结构与安装后的一致

内容的提问来源于stack exchange,提问作者Vagrant Nexus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 14:25:37