Как импортировать модули во встроенный код python для boost :: python? - PullRequest
11 голосов
/ 02 июня 2009

Я использую Boost :: Python для встраивания кода Python в приложение. Мне удалось правильно оценить операторы печати или другие выражения, но когда я пытаюсь импортировать модули, он не импортируется, и приложение закрывается. Кроме того, вызов функции globals () во встроенном коде также приводит к ошибке времени выполнения.

#include <boost/python.hpp>

using namespace boost;
using namespace boost::python;
using namespace boost::python::api;

int main(void) {
    Py_Initialize();
    object main_module = import("__main__");
    object main_namespace = main_module.attr("__dict__");
    main_namespace["urllib2"] = import("urllib2");

    object ignored = exec(
            "print 'time'\n", main_namespace);
}

Здесь я попытался импортировать urllib2, используя функцию форсированного импорта, он компилируется и работает правильно, но с помощью следующего оператора exec выдает ошибку.

    object ignored = exec(
            "print urllib2\n"
            "print 'time'\n", main_namespace);

Или когда я удаляю функцию форсированного импорта и выполняю импорт из встроенного кода, это выдает ошибку. Я попытался использовать блок try: exception:, но он тоже не работает. Это потому, что приложение C ++ не может найти расположение модуля urllib2 py или чего-то еще? Есть ли способ установить путь к модулю перед попыткой импорта?

Он создается только для внутреннего использования, поэтому допустимо некоторое жесткое кодирование путей.

Редактировать: Подробнее:
Это то, что происходит. Я сделал попытку ... поймал и вызвал PyErr_Print (), когда есть исключение, и получал это как ошибку все время, когда происходит импорт модуля или даже вызов функции. Сообщение об ошибке:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
TypeError: 'NoneType' object does not support item assignment

Кто-нибудь может подумать о какой-либо причине?

Ответы [ 3 ]

5 голосов
/ 02 июня 2009

Если вы еще этого не сделали, вам нужно

import sys
sys.path.append("/home/user/whatever")

Это решило мои проблемы пару лет назад при внедрении boost :: python (Python v2.5).

Edit:

Обшарил старый код. Возможно, это делает трюк:

Py_SetProgramName(argv[0]);
Py_InitializeEx(0);

Звучит неуверенно, что вам действительно нужен Py_SetProgramName(), но я слабо помню какой-то подозрительный бизнес там.

3 голосов
/ 11 июня 2009

Это не помогло, но я нашел другое решение моей проблемы. Мой текущий код выглядит так:

#include <boost/python.hpp>
#include <iostream>

using namespace std;
using namespace boost;
using namespace boost::python;
using namespace boost::python::api;

int main(void) {
        Py_Initialize();
        boost::python::object http = boost::python::import("urllib2");

        try
        {
                boost::python::object response = http.attr("urlopen")("http://www.google.com");
                boost::python::object read = response.attr("read")();
                std::string strResponse = boost::python::extract<string>(read);
                cout << strResponse << endl;
        }
        catch(...)
        {
                PyErr_Print();
                PyErr_Clear();
        }
}

В любом случае, спасибо за ответ Jonas

0 голосов
/ 03 июля 2009

Я столкнулся с той же проблемой, что и вы, то есть с очень простым примером, приводящим к ошибке TypeError, и нашел ответ в на этот вопрос , который должен был предоставить пространство имен дважды, как глобальное, так и локальное.

...