【问题标题】:How to wrap an anonymous enum in Cython and give it a name?如何在 Cython 中包装匿名枚举并为其命名?
【发布时间】:2017-03-22 19:10:31
【问题描述】:

我正在使用 Cython 包装一些 C++ 代码,并且在嵌套在两个命名空间中的匿名枚举存在一些问题。

来自some_header.hpp的示例定义:

namespace A {
    namespace B {
        enum {
            X = 0,
            Y = 1,
            Z = 2
        };
    }
}

上述头文件的我的.pxd文件:

cdef extern from 'some_header.hpp' namespace 'A::B':
    cdef enum:
        CX 'A::B::X'    \
        CY 'A::B::Y'     > Can this be simplified somehow?
        CZ 'A::B::Z'    /

我的.pyx 包装模块:

class B(IntEnum):
    X = CX    \
    Y = CY     > CX, CY and CZ are global in my .pyx module
    Z = CZ    /

我可以在我的.pyx 文件中使用CXCYCZ,如您在上面看到的,但如果我可以执行CB.XCB.YCB.Z 之类的操作,那就太好了, IE。 CX/CY/CZ 在我的模块中不会是全局的。

.pxd 中的扩展命名空间'A::B::X' 也可以简化或删除吗?

【问题讨论】:

    标签: python enums cython


    【解决方案1】:

    我自己没有尝试过 Cython 的 C++ 支持,但您是否尝试过简单地给枚举命名,很确定 Cython 并不关心引用的枚举是否是匿名的。无论如何,这些枚举值仍将在全局范围内。

    您也可以尝试使用 Cython 的 cpdef 定义这些枚举并节省一些输入,可能类似于:

    cdef extern from 'some_header.hpp' namespace 'A::B':
        cpdef enum B:
            X
            Y
            Z
    

    再说一次,这仅考虑 C 级 Cython 支持,所以我不太确定这是否完全适用于 C++ 代码。

    【讨论】:

    • Cython 接受此语法,但不幸的是 MSVC 抛出错误 C2039: 'B': is not a member of 'A::B'
    • @PythonFanboy 是的,我刚刚确认 Cython 确实依赖于枚举的名称定义。这在 C 中似乎不是问题,因为我认为该语言中缺少名称空间。那么我猜你没有比你已经拥有的更多的选择了。
    • 顺便说一句,我刚刚意识到您的主要担忧似乎是这些枚举最终会出现在您的 Cython 包装器的全局范围内。这绝对是有利于 Cython“提供”的接口模式的预期行为。换句话说,您应该将 C/C++ 标头包装在一个不同名称的 Cython 定义文件中,并从中包装cimport。你可以阅读docs.cython.org/en/latest/src/userguide/… 或者docs.cython.org/en/latest/src/userguide/…
    • 试试cpdef enum B "A::B": ...
    【解决方案2】:

    一种方法是创建一个非常小的pxd 文件,该文件仅在其命名空间内声明此枚举。这样,枚举在您的 Cython 代码的其余部分中有一个简单的命名空间。我可以让它在 OS X 上编译/工作:

    接口.pxd文件:

    # a.pxd
    cdef extern from "some_header.cpp" namespace "A::B":
        cdef enum:
            X
            Y
            Z
    

    还有演示代码

    cimport a
    
    cpdef foobar():
        return a.X, a.Y, a.Z # enum values are namespaced inside `a`
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多