Печать переменной во встроенном интерпретаторе Python - PullRequest
4 голосов
/ 03 марта 2012

Я написал небольшую программу на C, которая встраивает Python. Я правильно его настраиваю, используя Py_Initialize () и Py_Finalize (), и могу запускать скрипты, используя PyRun_SimpleString или PyRun_SimpleFile Однако я не знаю, как имитировать поведение собственного интерпретатора Python при печати переменных.

В частности:

a = (1, 2, 3)
print a

У меня отлично работает: распечатывает (1, 2, 3)

Тем не менее:

a = (1, 2, 3)
a

Ничего не печатает вообще. В собственном интерпретаторе Python это также выведет (1, 2, 3). Как я могу заставить мой код делать то, что ожидают пользователи, и распечатать значение?

Заранее спасибо!

1 Ответ

7 голосов
/ 03 марта 2012

Для запуска интерактивного цикла переводчиков необходимо использовать функцию PyRun_InteractiveLoop().В противном случае ваш код будет вести себя так, как если бы он был написан в файле сценария Python, а не введен в интерактивном режиме.

Редактировать : полный код простого интерактивного интерпретатора:

#include <Python.h>

int main()
{
    Py_Initialize();
    PyRun_InteractiveLoop(stdin, "<stdin>");
    Py_Finalize();
}

Edit2 : Реализация полноценного интерактивного интерпретатора в графическом интерфейсе - это немного проекта.Вероятно, самый простой способ сделать это правильно - написать базовый эмулятор терминала, подключенный к псевдо-терминальному устройству, и использовать приведенный выше код на этом устройстве.Это автоматически уладит все тонкости.

Если ваша цель - не полноценный интерактивный редактор, можно использовать PyRun_String() с Py_single_input в качестве стартового токена.Это позволит вам запускать некоторый код Python, как в интерактивном интерпретаторе, и если этот код оказался единственным выражением, которое не оценивается как None, представление его значения выводится - конечно же, на стандартный вывод.Вот пример кода (без проверки ошибок для простоты):

#include <Python.h>

int main()
{
    PyObject *main, *d;
    Py_Initialize();
    main = PyImport_AddModule("__main__");
    d = PyModule_GetDict(main);
    PyRun_String("a = (1, 2, 3)", Py_single_input, d, d);
    PyRun_String("a", Py_single_input, d, d);
    Py_Finalize();
}

Это напечатает (1, 2, 3).

Все еще много проблем:

  • Нет обработки ошибок и печати трассировки.
  • Нет "инкрементного ввода" для команд блока, как в интерактивном интерпретаторе.Ввод должен быть завершен.
  • Вывод на стандартный вывод.
  • Если задано несколько строк ввода, ничего не печатается.

Чтобы действительно воспроизвести поведениеинтерактивный переводчик не прост.Вот почему моя первоначальная рекомендация состояла в том, чтобы написать базовый эмулятор терминала в вашем графическом интерфейсе, который не должен быть слишком сложным - или, возможно, есть даже один доступный.

...