使用Cython cpdef enum封装C++枚举时如何避免C++和Python重复实现
Cython避免封装C++ enum class时重复定义的解决方案
这里提供两种可落地的方案,无需重复维护枚举的成员、取值:
方案1:拆分C层声明与Python层导出(推荐)
该方案得到的是Cython原生封装的PEP 435枚举,可直接传入C++接口,体验和直接在pyx中定义cpdef枚举完全一致。
- 首先在pxd中仅声明C侧的枚举类型,不要使用cpdef:
# my_enum.pxd cdef extern from "my_enum.h": cdef enum class fruit_t(unsigned char): none = 0x0 apple = 0x1 banana = 0x2 void like_fruit(fruit_t f)
- 在pyx文件中cpdef导出枚举时,直接复用C侧已声明的取值,无需硬编码重复值:
# my_cython_wrap.pyx from my_enum cimport * cpdef enum class fruit_t: none = fruit_t.none apple = fruit_t.apple banana = fruit_t.banana def py_like_fruit(fruit_t f): like_fruit(f)
后续如果需要新增/修改枚举成员,只需要更新pxd中的C声明部分,pyx侧的导出逻辑不需要改动取值,仅需新增成员名即可。
方案2:动态生成标准库Enum(适合纯Python兼容场景)
如果需要使用Python标准库的Enum类型而非Cython原生封装枚举,可以动态构造枚举类,完全避免重复定义:
# my_cython_wrap.pyx from my_enum cimport * from enum import Enum # 成员、取值全部从C侧枚举拉取,无需硬编码 fruit_t = Enum('fruit_t', { name: getattr(fruit_t, name) for name in ["none", "apple", "banana"] }) def py_like_fruit(fruit_t f): like_fruit(f.value)
如果枚举成员数量较多,还可以额外实现Cython枚举遍历逻辑,连成员名列表都无需手动维护,进一步降低重复代码。
内容的提问来源于stack exchange,提问作者ibarrond
相关产品推荐
相关产品推荐

