SWIG - конвертировать перечисление C ++ в перечисление Python - PullRequest
0 голосов
/ 15 мая 2018

Я работаю, чтобы перевести перечисление класса C ++ в перечисление python, используя swig.У меня есть следующая реализация в файле 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

Возникает вопрос: можно ли получить доступ к enum, как показано ниже, как мы используем в python?

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

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

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)
%}
0 голосов
/ 15 мая 2018

В отличие от вашего примера, SWIG 3.0.12 обернул бы ваш enum class пример как Color_RED, Color_BLUE и Color_GREEN. Вот пример, который добавляет некоторый дополнительный код Python для переназначения этого шаблона в Color.RED, Color.BLUE и Color.GREEN:

%pythoncode добавлено в часть Python оболочки SWIG. После загрузки расширения Python этот код запускается. Он собирает и удаляет переменные, начиная с prefix_ , переименовывает их без 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>
...