Cython中Candle类尺寸不匹配及属性缺失问题求助
看起来你在Cython模块编译和属性访问上遇到了两个棘手的问题,我来帮你一步步拆解解决:
先回顾下你的代码结构:
candle.pxd:定义Candle类的cdef属性
cdef class Candle: cdef: int ts
candle.pyx:实现Candle类的构造方法
cdef class Candle: def __init__(self, int ts): self.ts = ts
feeder.pyx:依赖Candle类的Feeder类
from src.cython.candle cimport Candle cdef class Feeder: cdef instantiate_first_candle(self): cdef int a = 1 # Instantiates Candle cdef Candle candle = Candle(a)
你遇到的两个错误分别是:
- 导入Feeder时抛出:
from src.cython.feeder import Feeder File "src/cython/candle.pxd", line 3, in init feeder ValueError: src.cython.candle.Candle has the wrong size, try recompiling. Expected 16, got 24
- IPython中能导入Candle,但实例化后访问
ts报错:
AttributeError: 'candle.Candle' object has no attribute 'ts'
一、解决类大小不匹配的ValueError
这个错误的核心原因是编译产物不一致:当你修改了candle.pxd或candle.pyx后,没有重新编译依赖它的feeder.pyx,导致feeder.so中使用的还是旧版本的Candle内存结构,和当前的Candle定义不匹配。
解决步骤:
- 彻底清理所有编译残留:
- 删除项目中所有
.c、.so(Linux/macOS)、.pyd(Windows)文件 - 如果用
setup.py编译,删除整个build目录
- 删除项目中所有
- 统一编译所有关联模块:
不要单独编译candle.pyx或feeder.pyx,要把它们放在同一个编译脚本里一起编译,确保所有模块使用的是同一个Candle定义。比如你的setup.py可以写成这样:from setuptools import setup from Cython.Build import cythonize setup( ext_modules=cythonize([ "src/cython/candle.pyx", "src/cython/feeder.pyx" ]) ) - 重新执行编译:运行
python setup.py build_ext --inplace(或者用你习惯的编译命令)
二、解决ts属性无法访问的AttributeError
你定义的ts是Cython私有cdef属性,默认只能在Cython代码内部访问,Python解释器看不到这个属性。要让Python层能访问,有两种方案:
方案1:将属性声明为public
修改candle.pxd,给ts加上public关键字:
cdef class Candle: cdef public int ts
重新编译后,就能在Python里直接访问candle.ts了。
方案2:添加Python层的getter方法(更安全)
如果不想直接暴露私有属性,可以在candle.pyx里添加一个Python可调用的方法来获取ts:
cdef class Candle: def __init__(self, int ts): self.ts = ts @property def ts(self): return self.ts
这样在Python中同样可以通过candle.ts获取值,但无法直接修改(如果需要修改可以再添加setter)。
总结提醒
- 每次修改
.pxd文件后,必须重新编译所有依赖它的模块,否则很容易出现结构不匹配的错误 - 尽量用统一的编译脚本管理所有Cython模块,避免手动编译导致的版本不一致问题
内容的提问来源于stack exchange,提问作者joaoavf
相关产品推荐
相关产品推荐

