Cython无法从.pxd文件cimport:编译失败问题求助
Cython跨文件cimport编译失败修复及最小可行示例
项目原结构
cythonize: ROOT |___ cythonize |___ __init__.pxd |___ __init__.py |___ first.pxd |___ first.pyx |___ second.pxd |___ second.pyx |___ README.md |___ setup.py
原文件内容
__init__.pxd:空文件__init__.py:空文件first.pxd:
cdef class MyClass: cdef str good cdef str bad cdef str say(self, str x, str y)
first.pyx:
cdef class MyClass: cdef str say(self, str x, str y): return x
second.pxd:
from . cimport first # removing this does not help
second.pyx:
#cython language_level=3 from . cimport first cdef first second(str a, str b): return first(a, b)
编译错误信息
执行命令 cythonize -i -k -3 cythonize/second.pyx 时出现以下错误:
>>> cythonize -i -k -3 cythonize/second.pyx Compiling C:\...\cythonize\cythonize\second.pyx because it changed. [1/1] Cythonizing C:\...\cythonize\cythonize\second.pyx Error compiling Cython file: ------------------------------------------------------------ ... #cython language_level=3 from . cimport first cdef first second(str a, str b): ^ ------------------------------------------------------------ cythonize\second.pyx:5:5: 'first' is not a type identifier Error compiling Cython file: ------------------------------------------------------------ ... #cython language_level=3 from . cimport first cdef first second(str a, str b): return first(a, b) ^ ------------------------------------------------------------ cythonize\second.pyx:6:11: 'first' is not a constant, variable or function identifier Failed compilations: cythonize.second
最小可行修复方案
错误核心是混淆了模块名和类型/函数名:first是模块名,不能直接当作类型或构造函数使用。需要明确引用模块内的MyClass类型,并补充实例创建逻辑。
修改后的文件内容
first.pxd(暴露类型和实例创建函数):
cdef class MyClass: cdef str good cdef str bad cdef str say(self, str x, str y) # 新增:定义可导出的实例创建函数 cdef MyClass create_myclass(str a, str b)
first.pyx(实现构造逻辑和函数):
cdef class MyClass: def __init__(self, str good, str bad): self.good = good self.bad = bad cdef str say(self, str x, str y): return x # 实现实例创建函数 cdef MyClass create_myclass(str a, str b): return MyClass(a, b)
second.pyx(正确引用模块内的类型和函数):
#cython language_level=3 from . cimport first # 明确指定返回类型为first模块的MyClass cdef first.MyClass second(str a, str b): return first.create_myclass(a, b)
编译方式
推荐用setup.py编译整个模块(避免单独编译的依赖缺失问题):
编写setup.py:
from setuptools import setup from Cython.Build import cythonize setup( ext_modules=cythonize("cythonize/*.pyx", language_level=3), package_dir={"": "."} )
执行编译命令:
python setup.py build_ext --inplace
或者用cythonize命令同时编译依赖文件:
cythonize -i -k -3 cythonize/first.pyx cythonize/second.pyx
内容的提问来源于stack exchange,提问作者Jim
相关产品推荐
相关产品推荐

