【问题标题】:SWIG- Convert C++ enum to Python enumSWIG-将 C++ 枚举转换为 Python 枚举
【发布时间】:2018-05-15 15:02:32
【问题描述】:

我正在努力使用 swig 将 C++ 类枚举转换为 python 枚举。我在 example.h 文件中有以下实现。

namespace colors{ 
 enum class Color{
    RED = 0,
    BLUE = 1,
    GREEN = 2
 };
}

我的 Swig 接口文件是

    %module api
%{
#include "example.h"
%}
%include "example.h"

但使用swig工具后界面提供如下用法

import pywarp_example as impl 
impl.RED

这里出现的问题是,是否可以像我们在 python 中使用的方式那样访问枚举?

impl.Color.RED Or impl.Color.RED.value

【问题讨论】:

标签: python c++ enums swig


【解决方案1】:

与您的示例不同,SWIG 3.0.12 会将您的 enum class 示例包装为 Color_REDColor_BLUEColor_GREEN。这是一个示例,它添加了一些额外的 Python 代码以将该模式重新映射到 Color.REDColor.BLUEColor.GREEN

%pythoncode 被添加到 SWIG 包装器的 Python 部分。在 Python 扩展加载后,此代码运行。它收集并删除以 prefix_ 开头的变量,重命名不带 prefix_ 的变量,然后创建一个名为 的类前缀将新变量作为类变量。

%module test

%inline %{
namespace colors{ 
 enum class Color{
    RED = 0,
    BLUE = 1,
    GREEN = 2
 };
}
%}

%pythoncode %{
from enum import Enum
def redo(prefix):
    tmpD = {k:v for k,v in globals().items() if k.startswith(prefix + '_')}
    for k,v in tmpD.items():
        del globals()[k]
    tmpD = {k[len(prefix)+1:]:v for k,v in tmpD.items()}
    # globals()[prefix] = type(prefix,(),tmpD) # pre-Enum support
    globals()[prefix] = Enum(prefix,tmpD)
redo('Color')
del redo  # cleaning up the namespace
del Enum
%}

使用示例:

>>> import test
>>> dir(test)
['Color', '__builtin__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_newclass', '_object', '_swig_getattr', '_swig_property', '_swig_repr', '_swig_setattr', '_swig_setattr_nondynamic', '_test']
>>> test.Color
<enum 'Color'>
>>> dir(test.Color)
['BLUE', 'GREEN', 'RED', '__class__', '__doc__', '__members__', '__module__']
>>> test.Color.BLUE
<Color.BLUE: 1>

【讨论】:

  • 非常感谢马克,有没有办法创建 python 枚举而不是类。
  • 我将 Enum 替换为 IntEnum 以允许将其用作函数参数
【解决方案2】:

可以使用此脚本将 C++ Enum 转换为 python Enum。

%pythoncode %{
from enum import Enum
def enum(prefix):
    tmpD = {k:v for k,v in globals().items() if k.startswith(prefix + '_')}
    for k,v in tmpD.items():
        del globals()[k]
    tmpD = {k[len(prefix)+1:]:v for k,v in tmpD.items()}
    globals()[prefix] = Enum(prefix,tmpD)
%}

【讨论】:

    猜你喜欢
    • 2020-08-21
    • 2021-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多