Python 在向量模板中使用嵌套枚举引用包装结构

Python 在向量模板中使用嵌套枚举引用包装结构,python,c++,enums,nested,cython,Python,C++,Enums,Nested,Cython,这是一天半以前的事了,但还没有收到任何回复,所以我正在一个更普通的论坛上碰碰运气 我一直在尝试各种方法来包装下面的代码,但有不同程度的错误。大量的搜索让我遇到了类似的问题,还有一张优秀的愿望清单,但老实说,我不确定我是否走上了正确的道路 犁头类型。h: namespace Plow { struct JobState { enum type { INITIALIZE = 0, RUNNING = 1, FINISHED = 2

这是一天半以前的事了,但还没有收到任何回复,所以我正在一个更普通的论坛上碰碰运气

我一直在尝试各种方法来包装下面的代码,但有不同程度的错误。大量的搜索让我遇到了类似的问题,还有一张优秀的愿望清单,但老实说,我不确定我是否走上了正确的道路

犁头类型。h:

namespace Plow {

    struct JobState {
      enum type {
        INITIALIZE = 0,
        RUNNING = 1,
        FINISHED = 2
      };
    };
    ...
    class JobFilterT {
     public:
      ...
      std::vector<JobState::type>  states;
      ...
cdef extern from "rpc/plow_types.h" namespace "Plow":

    enum JobState_type "Plow::JobState::type":
        INITIALIZE "Plow::JobState::INITIALIZE"
        RUNNING "Plow::JobState::RUNNING"
        FINISHED "Plow::JobState::FINISHED"

    struct JobState:
        JobState_type type
    ...
    cdef cppclass JobFilterT:
        vector[JobState_type] states 
cimport cython

@cython.internal
cdef class _JobState:
    cdef:
        readonly int INITIALIZE 
        readonly int RUNNING 
        readonly int FINISHED 

    def __cinit__(self):
        self.INITIALIZE = JOBSTATE_INITIALIZE
        self.RUNNING = JOBSTATE_RUNNING
        self.FINISHED = JOBSTATE_FINISHED

JobState = _JobState()
我得到一个错误:

src/plow.cpp: In function ‘std::vector<Plow::JobState::type, std::allocator<Plow::JobState::type> > __pyx_convert_vector_from_py_enum__Plow_3a__3a_JobState_3a__3a_type(PyObject*)’:
src/plow.cpp:6688: error: invalid conversion from ‘long int’ to ‘Plow::JobState::type’
src/plow.cpp:在函数“std::vector uuupyx_convert_vector_from_py_enum_uuuplow_3a_uu3a_JobState_3a_3a_3a_type(PyObject*)”中:
src/plow.cpp:6688:错误:从“long int”到“plow::JobState::type”的转换无效
或:
  • 如何正确包装此嵌套枚举
  • 这是否有必要尝试并准确地包装它,或者我是否可以通过其他方式实现访问这些“名称空间”常量的目标?我是否应该完全忽略这些结构,在pyx中定义自己的常量版本,并使用匹配的int值
    我试图在cython pyx中简单地定义我自己的常量版本,并将所有内容都视为int(
    vector[int]states
    ),但编译器抱怨不知道如何从
    int long
    转换到
    Plow::JobState::type
    ,我终于找到了答案,在尝试了大量令人难以置信的组合之后。这离我问这个问题之前的最后一次尝试不远了

    犁头类型。pxd:

    namespace Plow {
    
        struct JobState {
          enum type {
            INITIALIZE = 0,
            RUNNING = 1,
            FINISHED = 2
          };
        };
        ...
        class JobFilterT {
         public:
          ...
          std::vector<JobState::type>  states;
          ...
    
    cdef extern from "rpc/plow_types.h" namespace "Plow":
    
        enum JobState_type "Plow::JobState::type":
            INITIALIZE "Plow::JobState::INITIALIZE"
            RUNNING "Plow::JobState::RUNNING"
            FINISHED "Plow::JobState::FINISHED"
    
        struct JobState:
            JobState_type type
        ...
        cdef cppclass JobFilterT:
            vector[JobState_type] states 
    
    cimport cython
    
    @cython.internal
    cdef class _JobState:
        cdef:
            readonly int INITIALIZE 
            readonly int RUNNING 
            readonly int FINISHED 
    
        def __cinit__(self):
            self.INITIALIZE = JOBSTATE_INITIALIZE
            self.RUNNING = JOBSTATE_RUNNING
            self.FINISHED = JOBSTATE_FINISHED
    
    JobState = _JobState()
    
    我需要忘记
    JobState
    struct,只包装枚举。但我还需要将它们映射到cython中的新名称,以避免与使用类似名称空间技术的其他枚举发生名称冲突

    cdef extern from "rpc/plow_types.h" namespace "Plow":
    
        ctypedef enum JobState_type "Plow::JobState::type":
            JOBSTATE_INITIALIZE "Plow::JobState::INITIALIZE"
            JOBSTATE_RUNNING "Plow::JobState::RUNNING"
            JOBSTATE_FINISHED "Plow::JobState::FINISHED" 
    
    现在我可以在
    vector[JobState\u type]
    中引用
    JobState\u type
    。然后,我使用这种方法使我的常量以只读方式在python中可用:

    job.pyx:

    namespace Plow {
    
        struct JobState {
          enum type {
            INITIALIZE = 0,
            RUNNING = 1,
            FINISHED = 2
          };
        };
        ...
        class JobFilterT {
         public:
          ...
          std::vector<JobState::type>  states;
          ...
    
    cdef extern from "rpc/plow_types.h" namespace "Plow":
    
        enum JobState_type "Plow::JobState::type":
            INITIALIZE "Plow::JobState::INITIALIZE"
            RUNNING "Plow::JobState::RUNNING"
            FINISHED "Plow::JobState::FINISHED"
    
        struct JobState:
            JobState_type type
        ...
        cdef cppclass JobFilterT:
            vector[JobState_type] states 
    
    cimport cython
    
    @cython.internal
    cdef class _JobState:
        cdef:
            readonly int INITIALIZE 
            readonly int RUNNING 
            readonly int FINISHED 
    
        def __cinit__(self):
            self.INITIALIZE = JOBSTATE_INITIALIZE
            self.RUNNING = JOBSTATE_RUNNING
            self.FINISHED = JOBSTATE_FINISHED
    
    JobState = _JobState()
    
    这给了我一个带有只读常量属性的
    JobState
    的公共实例

    当需要从python值列表转换回
    向量[JobState\u type]
    时,我会这样做:

    someList = [JobState.RUNNING]
    ...
    cdef:
        JobState_type i
        vector[JobState_type] vec_states
    
    for i in someList:
        vec_states.push_back(i)
    

    是否有理由不使用命名空间?在C++中我正在打包?C++代码位于代码>犁< /COD>命名空间内。谢谢。通过singleton类将枚举值作为只读常量公开的好主意。这对我不起作用。当我做同样的事情时,我的类上的那些属性不再是int。它们属于“getset_描述符”类型。我无法将枚举传递给声明使用该枚举的函数。它抱怨我没有给它一个机会int@eric.frederich,这将继续在我维护的两个不同的代码库中工作。您是否有一个可用的要点,说明您是如何实现它的?另外,因为Python没有枚举类型,所以这种方法实际上并没有给您类型安全性。如您所见,它们被简单地转换为int字段。如果您希望使用Python公开的类型安全枚举,那么您可能必须采用另一种方法,即使用类似于
    .value()
    方法的基类类型。然后为每个枚举对其进行子类化。然后可以接受基类作为类型。