чтение глобальной переменной python в c

Я пытаюсь научиться правильно использовать API Python/C - все, что мне действительно нужно сделать, это прочитать глобальную переменную (в моем случае словарь, но я начинаю с простой целочисленной переменной). Используя обсуждение: Как получить доступ к глобальной переменной Python из C? и источник ответа: http://bytes.com/topic/python/answers/705918-c-api-embedded-python-how-get-set-named-variables Я написал эту маленькую штуку :

Код Python (tryStuff.py):

var1 = 1

var2 = ['bla', 'blalba']

var3 = {"3" : "Three", "2" : "Two", "1" : "One", "0" : "Ignition!"}

print "end of file - tryStuff!!"

Код C (embedPythonTry.c):

#include <python2.7/Python.h>

int main(int argc, char **argv){
  Py_Initialize();
  PyRun_SimpleString("import sys");
  PyRun_SimpleString("sys.path.append('<the absolute path of the folder in which the python file is located>')");
  PyImport_ImportModule("tryStuff");
  printf("After the import, before the addition\n");
  PyObject *mainModule = PyImport_AddModule("__main__");
  PyObject *var1Py = PyObject_GetAttrString(mainModule, "var1");
  int var1Int = PyInt_AsLong(var1Py);
  printf("var1=%d ; var1==NULL: %d\n", var1Int, var1Py==NULL);
  Py_XDECREF(var1Py);
  Py_Finalize();
  return 0;
}

Результат запуска этой программы c:

end of file - tryStuff!!
After the import, before the addition
var1=-1 ; var1==NULL: 1

Это означает, что интерпретатор Python находит и запускает правильный скрипт Python, но почему-то не может прочитать переменную (var1).

Может ли кто-нибудь определить проблему - я уже потерялся. Кажется, самая простая ситуация, которая может быть для применения Python/C API, но это не работает. Что мне не хватает?


person et_l    schedule 14.07.2014    source источник


Ответы (2)


Вы должны вызвать PyObject_GetAttrString по результату PyImport_ImportModule. Я понятия не имею, почему вы думаете, что модуль __main__ должен определять эту переменную:

PyObject *mod = PyImport_ImportModule("tryStuff");
PyObject *var1Py = PyObject_GetAttrString(mod, "var1");

Вы также должны добавить проверку результатов, так как PyImport_ImportModule может возвращать NULL в случае сбоя импорта.

person Bakuriu    schedule 14.07.2014
comment
Спасибо! Я знаю о необходимости проверки результатов, но сначала хотел начать. Что касается моей путаницы - я последовал примеру из обсуждения, связанного выше, и тому факту, что в документации модуль main упоминается как глобальная среда работающего интерпретатора. Как-то я не заметил, что функция PyImport_ImportModule возвращает значение (в примере они проигнорировали это значение, и я действительно пытался понять, как мне получить объект модуля). - person et_l; 14.07.2014

Я знаю, что этот вопрос возник давно, но это для тех, кто наткнулся на это во время поиска в Google.

ОП говорит, что его код не работает, но по иронии судьбы его код работал у меня лучше, чем другие примеры. (Спасибо, @et_l)

Итак, ответ - как получить доступ к переменным Python из C - для кода OP (с кодом основного модуля, написанным OP);

#include <stdio.h>
#include <Python.h>

int main () {
  Py_Initialize();
  PyRun_SimpleString("var1 = 1");
  PyRun_SimpleString("var2 = ['bla', 'blalba']");
  PyRun_SimpleString("var3 = {'3' : 'Three', '2' : 'Two', '1' : 'One', '0' : 'Ignition!'}");
  PyRun_SimpleString("print('end of file - tryStuff!!')");

  PyObject *mainModule = PyImport_AddModule("__main__");
  PyObject *var1Py = PyObject_GetAttrString(mainModule, "var1");
  int c_var1 = PyLong_AsLong(var1Py);
  printf("var1 with C: %d\n", c_var1);

  Py_Finalize();
  return 0;
}
person Du Brisingr Arget    schedule 01.10.2020
comment
Спасибо за комментарий! Ответ @Bakuriu на самом деле правильный на мой вопрос. Обратите внимание, что в вашем коде вы: 1) инициализируете интерпретатор Python 2) определяете переменные, используя PyRun_SimpleString файла c, то есть определяете их в основном модуле (где вы находитесь, когда запускаете интерпретатор) 3) извлекаете переменные из основного модуль, который имеет смысл в вашей ситуации. Но в моем первоначальном вопросе переменные были определены в модуле Python, который я импортировал с использованием метода PyImport_ImportModule файла c. Таким образом, переменные не принадлежали основному модулю. - person et_l; 05.10.2020