SWIG- 将 C++ 枚举转换为 Python 枚举
SWIG- Convert C++ enum to Python enum
我正在努力使用 swig 将 C++ class 枚举转换为 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
与您的示例不同,SWIG 3.0.12 会将您的 enum class
示例包装为 Color_RED
、Color_BLUE
和 Color_GREEN
。这是一个添加一些额外的 Python 代码以将该模式重新映射到 Color.RED
、Color.BLUE
和 Color.GREEN
:
的示例
%pythoncode
添加到 SWIG 包装器的 Python 部分。 Python 扩展加载后,此代码运行。它收集并删除以 prefix_ 开头的变量,不带 prefix_[= 重命名它们33=],然后创建一个名为 prefix 的 class,并将新变量作为 class 变量。
%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>
C++ 枚举可以使用此脚本转换为 python 枚举。
%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)
%}
我正在努力使用 swig 将 C++ class 枚举转换为 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
与您的示例不同,SWIG 3.0.12 会将您的 enum class
示例包装为 Color_RED
、Color_BLUE
和 Color_GREEN
。这是一个添加一些额外的 Python 代码以将该模式重新映射到 Color.RED
、Color.BLUE
和 Color.GREEN
:
%pythoncode
添加到 SWIG 包装器的 Python 部分。 Python 扩展加载后,此代码运行。它收集并删除以 prefix_ 开头的变量,不带 prefix_[= 重命名它们33=],然后创建一个名为 prefix 的 class,并将新变量作为 class 变量。
%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>
C++ 枚举可以使用此脚本转换为 python 枚举。
%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)
%}