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

Cython跨pyx文件cimport报ModuleNotFoundError问题咨询

问题成因

报错的核心原因是Cython扩展的模块声明路径、源码存放位置和实际导入路径不匹配:

  • 你在setup.py中声明扩展模块的全限定名是lst_viewer.extensions.instrument,也就是说编译完成后,这个模块属于lst_viewer.extensions包下的子模块,不存在顶层名为instrument的模块。
  • 你在read_events.pyx中写from instrument cimport ...时,Cython编译阶段会扫描当前工作目录找到根目录extensions/下的instrument.pxd,因此能正常通过编译;但运行时Python会按照模块全路径查找顶层instrument模块,自然会抛出ModuleNotFoundError。
  • 你之前在根目录extensions/下加__init__.pxd无效,是因为这个目录本身不在Python包搜索路径内,你把Cython源码(.pyx/.pxd)和实际发布的Python包(src/lst_viewer/)分开放置,本身就不符合Python模块的查找规则,安装后根本不会把根目录的.pxd文件打包进去。
修正方案

按以下步骤调整即可解决问题:

  1. 调整目录结构
    把根目录extensions/下的所有Cython源文件(instrument.pxd、instrument.pyx、read_events.pyx)移动到src/lst_viewer/extensions/目录下,和已有的__init__.py同级,同时在该目录下新增空的__init__.pxd文件标记Cython包,调整后结构如下:
lst_viewer/
    setup.py
    src/
        lst_viewer/
            extensions/
                __init__.py
                __init__.pxd
                instrument.pxd
                instrument.pyx
                read_events.pyx
  1. 修正setup.py配置
    删掉重复导入的distutils.core相关语句,同时修改Extension的源文件路径,匹配新的源码位置:
import os
from Cython.Distutils import build_ext as cython_build_ext
from setuptools import find_packages, setup, Extension

EXTENSIONS = [
    Extension(
        'lst_viewer.extensions.instrument',
        sources=[os.path.join('src', 'lst_viewer', 'extensions', 'instrument.pyx')]
    ),
    Extension(
        'lst_viewer.extensions.read_events',
        sources=[os.path.join('src', 'lst_viewer', 'extensions', 'read_events.pyx')]
    ),
]

CMDCLASS = {'build_ext': cython_build_ext}

setup(
    name="lst_viewer",
    packages=find_packages('src'),
    include_package_data=True,
    package_dir={'': 'src'},
    ext_modules=EXTENSIONS,
    cmdclass=CMDCLASS
)
  1. 修正cimport导入路径
    修改read_events.pyx中的导入语句,使用和模块声明一致的全限定路径:
from lst_viewer.extensions.instrument cimport Instrument, get_instrument

def read_events(str instrument_name):
    cdef Instrument instr = get_instrument(instrument_name)
  1. 清理旧编译产物后重新编译
    先删除之前生成的build/目录、所有自动生成的.c/.so编译缓存文件,再执行pip install -e .或者python setup.py build_ext --inplace重新编译安装即可。

注意:如果需要在同包的Cython模块间简化导入,也可以在__init__.pxd中重导出需要的符号,但直接写全限定路径是最稳妥、不会出现路径查找问题的写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 04:45:48