如何在cython中按值访问枚举类型

Ben*_*Ben 3 python enums cython

我收到了一些看起来像这样的代码:

在"header.hpp"中:

enum class my_enum_type {
    val1 = 0;
    ... 
}
Run Code Online (Sandbox Code Playgroud)

在"header_lib.pyx"中:

cdef extern from "header.hpp":
    enum my_enum_type:
        val1 = 0;
        ...
...
Run Code Online (Sandbox Code Playgroud)

稍后在"header_lib.pyx"中:

def foo():
    ...
    return my_enum_type.val1
Run Code Online (Sandbox Code Playgroud)

我被告知这应该没有问题,但是从我刚才的经验来看并非如此,并且在这篇文章中很明显:在Cython代码中定义将在代码的C部分中使用的枚举.

但是,如果我写"return val1",它本身也不会识别"val1".这样做的正确方法是什么?

Sau*_*tro 8

你可以enum在Cython中声明一个:

ctypedef enum options: OPT1, OPT2, OPT3
Run Code Online (Sandbox Code Playgroud)

要么

ctypedef enum options:
    OPT1,
    OPT2,
    OPT3
Run Code Online (Sandbox Code Playgroud)

而且例子可能是:

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')
Run Code Online (Sandbox Code Playgroud)

跑步时main()你会看到"OPT2"打印.您可以将此变量传递test给函数CC++函数,其方式与此处显示的cdef函数相同.

  • 请注意,OP询问`enum class`而不是`enum`. (4认同)

iba*_*ond 5

为了保持 Cython/C/C++ 枚举类和 Python 枚举类功能的二元性,我提出了一种使用镜像类的解决方案。该解决方案分为两个部分:

  1. 一方面,我们有一个 Cython/C/C++ 枚举。该枚举可以通过将 C/C++ 代码包装在 extern 块中来生成...

     cdef extern from "header.h":
         enum my_c_enum_type:
             OPT1 = 0,
             OPT2,
             OPT3,
    
    Run Code Online (Sandbox Code Playgroud)

    ...或直接在 Cython 中。

     ctypedef enum my_cy_enum_type:
         OPT1=0,    #Default value is 0
         OPT2,      #Default value is 1
         OPT3,      #Default value is 2
    
    Run Code Online (Sandbox Code Playgroud)
  2. 另一方面我们有Python。从 Python 3.4 开始,有一个受支持的类 Enum 可以模拟该功能(链接到官方文档)。这里我们应该在纯 Python 中复制枚举元素。您可以使用该auto函数来填充 Enum,就像在 C/C++/Cython 中一样:

     from enum import Enum, auto
     class my_py_enum_type(Enum):
         OPT1=0
         OPT2=auto()
         OPT3=auto()
    
    Run Code Online (Sandbox Code Playgroud)

现在,为了使用这个双重 Python 和 Cython 解决方案:

 cdef extern from "header.h":
     enum my_c_enum_type:
         OPT1 = 0,
         OPT2,
         OPT3,
Run Code Online (Sandbox Code Playgroud)

此解决方案将 Cython/C 枚举(在 Python 中只是整数)转换为具有相同特征的适当 Python Enum 类,并将 Python Enum 对象内的值转换为原始 Cython 类。您将获得两全其美!