如何在Python中导入Cython生成的C模块,解决部署时导入报错问题
Cython模块导入错误排查与解决方案
首先排除核心低级错误
你当前的代码存在函数名不匹配问题:你在executor_unpack.pyx中定义的可导出函数名为executor_read,但导入语句写的是导入executor_unpack,本地能运行大概率是你本地留存了旧版本的编译产物包含该名称函数,重新编译后该名称函数不存在就会报错。
修正方案二选一:
- 把导入语句改为
from app.CythonOperations import executor_read - 把pyx文件中的
cpdef executor_read(list results)改为cpdef executor_unpack(list results)
排查编译与路径配置问题
你怀疑Python3不识别cpdef函数是错误的:cpdef本身就是Cython提供的、可直接被Python层调用的函数修饰符,只有cdef修饰的函数无法被Python直接导入,该逻辑不存在版本兼容问题。
你遇到的部署报错主要是环境构建和路径问题,按以下步骤逐一排查:
调整目录结构
需要把executor_unpack.pyx文件放到app/CythonOperations目录下,同时保证该目录下存在空的__init__.py文件,Python才能将该目录识别为合法的可导入包。配置编译流程
仅存.c文件无法直接被Python导入,必须把C代码编译为对应平台的动态链接库(Linux环境下为.so文件,Windows为.pyd)才能被识别,本地能运行是因为你已经在本地完成了编译,云环境未执行编译步骤就会找不到模块。
你需要在项目根目录新增setup.py用于编译Cython模块,示例代码如下:from setuptools import setup, Extension from Cython.Build import cythonize # 如果是直接编译已生成的.c文件,用下面的配置即可,不需要依赖cython环境 # ext_modules = [Extension("app.CythonOperations.executor_unpack", ["app/CythonOperations/executor_unpack.c"])] # 如果是从pyx源文件编译,用下面的配置 ext_modules = cythonize("app/CythonOperations/executor_unpack.pyx") setup(ext_modules=ext_modules)修正部署构建步骤
不要直接上传本地编译好的动态链接库,本地编译产物和Okteto Cloud的Linux环境、Python版本、CPU架构大概率不兼容,必须在云环境的构建流程中执行编译命令:
该命令会自动完成编译,并把生成的python setup.py build_ext --inplace.so文件直接放到app/CythonOperations目录下。兜底排查路径问题
如果执行完以上步骤仍然报错,可以在导入代码前加入调试代码,确认Python搜索路径和目录下的文件是否正确:import sys import os # 打印Python当前的模块搜索路径 print(sys.path) # 打印CythonOperations目录下的所有文件,确认.so编译产物是否存在 print(os.listdir(os.path.abspath("app/CythonOperations")))
内容的提问来源于stack exchange,提问作者Martin Mashalov
相关产品推荐
相关产品推荐

