Python C API:打开PyObject类型

时间:2010-06-22 11:53:46

标签: python c python-c-api python-c-extension

我有一些代码可以将Python与C ++接口,但是每次看到它都会很好,但我认为必须有更好的方法来实现它。在C ++方面,有一个'variant'类型可以处理固定范围的基本类型 - int,real,string,variant变量等。我有一些代码使用Python API从等效的Python类型转换。它看起来像这样:

variant makeVariant(PyObject* value)
{  
  if (PyString_Check(value)) {
    return PyString_AsString(value);
  }
  else if (value == Py_None) {
    return variant();
  }
  else if (PyBool_Check(value)) {
    return value == Py_True;
  }
  else if (PyInt_Check(value)) {
    return PyInt_AsLong(value);
  }
  else if (PyFloat_Check(value)) {
    return PyFloat_AsDouble(value);
  }
  // ... etc

问题是链式if-else ifs。它似乎是在调用switch语句,或者由类型标识符键入的创建函数的表或映射。换句话说,我希望能够写出类似的内容:

  return createFunMap[typeID(value)](value);

基于API文档的浏览,直接在这里获取'typeID'的最佳方法并不明显。我看到我可以这样做:

  PyTypeObject* type = value->ob_type;

这显然让我很快得到了类型信息,但是使用它来解决我感兴趣的有限类型的最简洁方法是什么?

1 个答案:

答案 0 :(得分:3)

在某种程度上,我认为你已经回答了自己的问题。

在某个地方,您将不得不根据数据选择功能。在C中执行此操作的方法是使用函数指针。

创建一个object_type->函数映射器的映射...其中每个函数都有一个明确定义的接口。

variant PyBoolToVariant(PyObject *value) {
    return value == Py_True;
}

Map<PyTypeObject*,variant* (PyObject*)> function_map;

function_map.add(PyBool, PyBoolToVariant);

现在你的makeVariant看起来像这样。

variant makeVariant(PyObject *value) {
    return (*function_map.get(value->ob_type))(value);
}

困难的部分是为Map对象提供正确的语法。另外,我假设有一个可以使用的Map对象,它接受类型参数(<PyTypeObject*, variant*(PyObject*))。

对于第二种类型的Map,我可能还没有完全正确的语法。它应该是一个指向函数的指针,该函数接受一个指针并返回指向变量的指针。

我希望这有用。