Cython如何从模块中导入全局C变量?
问题原因
你定义的cdef int myvar是Cython的C级全局变量,默认不会暴露为Python层可访问的属性,也无法被其他Cython模块直接识别,因此前两个测试场景无法正常获取变量,第三个场景需要配套.pxd声明才能生效。
方案1:仅用.pyx文件实现(无需.pxd)
如果不需要在C级操作变量,只是要在Python/Cython代码里读写值,直接在mymod.pyx里为C变量封装Python读写接口即可:
# 修改后的mymod.pyx cdef int myvar = 0 # 必须初始化避免取到随机值 # 封装为Python可访问的属性 @property def myvar(): return myvar @myvar.setter def myvar(int new_val): global myvar myvar = new_val
使用方式和普通Python模块属性完全一致,纯Python文件和Cython文件都支持:
# myapp.pyx / myapp.py import mymod print(mymod.myvar) # 正常输出值 mymod.myvar = 456 # 可以正常赋值
这个方案的缺点是读写会走Python对象包装,有微小的性能开销,适合非高频操作的场景。
方案2:使用.pxd文件实现C级导入(无性能开销)
如果需要在其他Cython模块的C级代码里直接操作原生int类型的myvar,就必须使用.pxd文件,步骤如下:
- 新建和模块同名的
mymod.pxd文件,存放C级声明:
# mymod.pxd cdef int myvar
- 修改原mymod.pyx,从同模块的pxd中导入变量:
# mymod.pyx from mymod cimport myvar # 后续和之前一样正常操作myvar即可 myvar = 123
- 其他Cython文件直接用cimport导入即可拿到原生C int类型的变量:
# myapp.pyx from mymod cimport myvar # 直接在C级代码中使用,无Python包装开销 cdef int calc_result = myvar * 10 + 5
注意:cimport语法只能在Cython的.pyx/.pxd文件中使用,纯Python的.py文件无法使用该方式导入。
内容的提问来源于stack exchange,提问作者Dan D
相关产品推荐
相关产品推荐

