【问题标题】:Python enum34 like interface for boost python enumPython enum34 like interface for boost python enum
【发布时间】:2016-02-15 14:37:40
【问题描述】:

我想通过类似于 enum34 包的字符串获取枚举:

Color['red'] == Color.red

如果我使用 boost::python 枚举执行此操作,我会得到:

TypeError: 'type' 对象没有属性 'getitem'

当然 boost 版本没有 getitem 方法。因此,要将这个方法添加到一个类中,我需要覆盖元类,但是在已经定义的类上更改它看起来很可疑。另一种可能性是创建一些代理类,但我不知道如何在全球范围内轻松应用它(返回代理的方法,包含代理而不是原始类的结构......) 还有其他可能吗?

【问题讨论】:

  • 刚刚找到了另一种直接在 C++ 中实现的方法: 1. 从 boost::python::enum_ 的 ob_type 中获取 PyTypeObject 2. 复制这个 PyTypeObject(因为这是所有人共享的) boost enums) 3. 使用 getitem 函数将 PyMappingMethods 结构添加到 tp_as_mapping 4. 将修改后的 PyTypeObject 添加为新的 ob_type
  • 将其添加为答案,然后在两天内接受。 :)

标签: python c++ boost enums


【解决方案1】:

我现在正在使用以下解决方法:

PyObject *enum_type = reinterpret_cast<PyObject *>(testEnum.ptr());

// get the metatype and make a copy
PyTypeObject *pto = reinterpret_cast<PyTypeObject *>(enum_type->ob_type);
PyTypeObject *new_pto = new PyTypeObject();
memcpy(new_pto, pto, sizeof(PyTypeObject)); 

// define a new mapping method
PyMappingMethods *mapping = new PyMappingMethods();
mapping->mp_subscript = convertEnum,

// replace the old mapping method and overwrite the meta type in the enum
new_pto->tp_as_mapping = mapping;
enum_type->ob_type = new_pto;

和枚举转换函数:

static PyObject* convertEnum(PyObject *self, PyObject *args) {
    auto resultEnum = enumfromString(PyString_AsString(args));
    return incref(object(resultEnum).ptr());
}

带有python测试的源码可以在https://github.com/CymricNPG/cpython/tree/enum找到

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    • 2016-05-25
    • 1970-01-01
    相关资源
    最近更新 更多