我收到了一些看起来像这样的代码:
在“header.hpp”中:
enum class my_enum_type {
val1 = 0;
...
}
在“header_lib.pyx”中:
cdef extern from "header.hpp":
enum my_enum_type:
val1 = 0;
...
...
稍后在“header_lib.pyx”中:
def foo():
...
return my_enum_type.val1
我被告知这应该没有问题,但从我刚才的经历来看并非如此,并且在这篇文章中可以看出:Defining enums in Cython code that will be used in the C part of code。
但是,如果我写“return val1”,它本身也不会识别“val1”。这样做的正确方法是什么?
答案 0 :(得分:7)
您可以在Cython中将enum
声明为:
ctypedef enum options: OPT1, OPT2, OPT3
或
ctypedef enum options:
OPT1,
OPT2,
OPT3
而且例子可能是:
def main():
cdef options test
test = OPT2
f(test)
cdef void f(options inp):
if inp == OPT1:
print('OPT1')
elif inp == OPT2:
print('OPT2')
elif inp == OPT3:
print('OPT3')
运行main()
时,您会看到"OPT2"
已打印。您可以将变量test
传递给C
或C++
函数,其方式与cdef
函数的显示方式相同。
答案 1 :(得分:1)
在解决了这个问题几个小时之后,我终于找到了合适的解决方案!实际上,这就是我希望Cython为我做的事情。
此解决方案分为两个部分:
一方面,我们有一个Cython枚举。这个枚举可以通过将C / C ++代码包装在extern块中来产生...
cdef extern from "header.hpp":
enum my_c_enum_type:
val1 = 0;
val2 = 1;
val3 = 2;
...或直接在Cython中
ctypedef enum my_c_enum_type:
val1, #Default value is 0
val2, #Default value is 1
val3 #Default value is 2
另一方面,我们有Python。从Python 3.4开始,有一个支持的类Enum可以模拟该功能(link to official documentation)。在这里,我们应该在纯Python中复制枚举:
from enum import Enum
class my_p_enum_type(Enum):
UNDEFINED=0
INTEGER=1
FRACTIONAL=2
BATCH=3
现在,我们有了一个功能相同的精美python类。为了在Python和Cython世界之间进行交互,我们使用:
# from Python to Cython
def func(enum_obj):
if not isinstance(enum_obj, my_p_enum_type):
raise TypeError
# Use in a cython function that accepts only my_c_enum_type Cython enum
myCythonEnumFunc(enum_obj.value)
...
# from Cython to Python
def func():
# a Cython enum
cdef my_c_enum_type a_cython_enum = val1
# creating a python enum
return my_p_enum_type(a_cython_enum)
...
此解决方案将Cython / C枚举(在Python中仅是整数)转换为具有相同特征的适当Python Enum类,并将Python Enum对象内部的值转换为原始Cython类。缺点是您仍然需要维护两个具有相同结构的不同代码段……但是您始终需要使用Cython来做到这一点!