如何在C / C ++扩展模块中创建Python代码中定义的类的新实例?

时间:2013-04-19 06:06:02

标签: python c extending

正如消息主题所说:我如何在C / C ++扩展模块中创建一个在Python代码中定义的类的新实例?我将在下面提供更多信息。< / p>

注意#1:我正在尝试使用Python / C API执行此操作,如下所示。但任何其他替代解决方案对我来说也是可以接受的〜)

我有一个Python文件,CppInterop.py:

import CppProxy

class RealTimeData:
    def __init__(self, id, value):
        self.id = id
        self.value = value

def writeAll():
    dataList= []
    dataList.append(RealTimeData("ID::001", 1.0))
    dataList.append(RealTimeData("ID::002", 2.0))
    dataList.append(RealTimeData("ID::003", 3.0))
    count = CppProxy.WriteRealTimeDataList(dataList)
    print count

def readAll():
    dataList = CppProxy.ReadRealTimeDataList()  # Try to read the list back
    for data in dataList:
        print "id: ", data.id
        print "value: ", data.value
    pass

if __name__ == '__main__':
    writeAll()
    readAll()

在“ readAll ”函数中,我想将存储在C / C ++模块中的列表读回Python代码,然后打印每个元素。

预计从CppProxy返回的“dataList”是包含类RealTimeData 元素的列表(如开头所定义)。

为此,我认为在我的C / C ++模块扩展代码中,我需要创建一个PyList实例,然后创建一些RealTimeData实例。可能是这样的:

static
PyObject * ReadRealTimeDataList(PyObject * self, PyObject * args)
{
    // Create a new Python list, size of which is zero.
    PyObject * listObj = PyList_New(0);
    if (NULL == listObj)
    {
        return NULL;
    }

    // Append some elements to the list
    for (int i = 0; i < 3; ++i)
    {
        // How can I create a RealTimeData instance here and assign it to dataObj?
        PyObject * dataObj;

        PyObject * idObj = PyString_FromString("some id");
        PyObject_SetAttrString(dataObj, "id", idObj);

        PyObject * valueObj = PyFloat_FromDouble((double)i);
        PyObject_SetAttrString(dataObj, "value", valueObj);

        if (PyList_Append(listObj, dataObj) != 0)
        {
            // error!
            return NULL;
        }
    }

    // return the list object to Python part
    return Py_BuildValue("O", listObj);
}

我读了this SO question。我是否需要执行与定义新的PyTypeObject以描述Python类RealTimeData相同的内容,然后创建它的新实例?

但我认为实际上从C ++代码中引入了一个新的类类型,而不是重用已经在Python代码中定义的类类型。

感谢任何帮助!

1 个答案:

答案 0 :(得分:4)

Python定义的类在Python / C扩展中实例化,与Python完全相同:通过导入并调用类对象:

// obtain the RealTimeData class
PyObject *get_RealTimeData()
{
    PyObject *module = PyImport_ImportModule("CppInterop");
    if (!module)
      return NULL;
    return PyObject_GetAttrString(module, "RealTimeData");
}

static
PyObject *ReadRealTimeDataList(PyObject *self, PyObject *args)
{
  static PyObject *RealTimeData = get_RealTimeData();
  ...

    // instantiate the class like you would in Python - by
    // calling the class object
    dataObj = PyObject_CallFunction(RealTimeData, "sd", "some id", 0.0);
    if (!dataObj)
      return NULL;
    ...
}

几个不相关的说明:

  • RealReadTimeDataList由于某种原因没有返回数据列表,而是一个保存列表的单元素元组。由于您的Python代码需要列表本身,因此只需返回listObj
  • 缺少错误检查:代码未检查PyString_FromStringPyFloat_FromDoublePyObject_SetAttrString的结果。
  • Py_DECREF(listObj)失败时应调用
  • PyList_Append。如上所述,在这种情况下,代码会泄漏listObj