Как эффективно построить словарь Python в C ++ - PullRequest
4 голосов
/ 08 декабря 2011

По соображениям производительности я хочу перенести части моей программы на Python на C ++ и поэтому пытаюсь написать простое расширение для моей программы.Часть C ++ создаст словарь, который затем должен быть доставлен в программу Python.

Один из найденных мной способов состоит в том, чтобы построить мой подобный объект в C ++, например, boost::unordered_map, а затемпереведите его на Python, используя метод Py_BuildValue [1] , который способен генерировать Python dicts.Но этот метод, который включает в себя преобразование контейнера в строковое представление и обратно, кажется слишком сложным «за углом», чтобы быть наиболее эффективным решением!?

Так что мой вопрос: Что является наиболееэффективный способ создания словаря Python в C ++? Я видел, что boost имеет библиотеку Python, которая поддерживает отображение контейнеров между C ++ и Python, но я до сих пор не нашел нужную вещь в документации.Если есть такой способ, я бы предпочел напрямую создавать Python dict в C ++, так что копирование и т. Д. Не требуется.Но если самый эффективный способ сделать это - другой, мне тоже хорошо.

Вот (упрощенный) C ++ - код, который я компилирую в .dll / .pyd:

#include <iostream>
#include <string>
#include <Python.h>
#include "boost/unordered_map.hpp"
#include "boost/foreach.hpp"

extern "C"{
typedef boost::unordered_map<std::string, int> hashmap;

static PyObject*
_rint(PyObject* self, PyObject* args)
{
    hashmap my_hashmap; // DO I NEED THIS?
    my_hashmap["a"] = 1; // CAN I RATHER INSERT TO PYTHON DICT DIRECTLY??
    BOOST_FOREACH(hashmap::value_type i, my_hashmap) {
            // INSERT ELEMENT TO PYTHON DICT
    }
    // return PYTHON DICT
}

static PyMethodDef TestMethods[] = {
    {"rint", _rint, METH_VARARGS, ""},
    {NULL, NULL, 0, NULL}
};

PyMODINIT_FUNC
inittest(void)
{
    Py_InitModule("test", TestMethods);
}

} // extern "C"

Это я хочу использовать в Python как:

import test
new_dict = test.rint()

Словарь отобразит строки в целые числа.Спасибо за любую помощь!

1 Ответ

5 голосов
/ 08 декабря 2011
  • Используйте API CPython напрямую yes:
    PyObject *d = PyDict_New()
    for (...) {
      PyDict_SetItem(d, key, val);
    }
    return d;
  • Или напишите объект python, который эмулирует dict, переопределив __setitem__ и __getitem__.В обоих методах используйте ваш оригинальный хэш-карту.В конце концов, копия не произойдет!
...