Эмуляция поведения Python оболочки "возвращаемое значение" - PullRequest
4 голосов
/ 25 мая 2020

Представьте, что у меня есть список JSON строк Python для оценки. Например, возможно, я создаю клиент-сервер Python GUI.

Обычный интерпретатор Python удобен тем, что он показывает «псевдовозвращаемое значение» каждой строки, например это:

 $ python3 -c "import code; code.interact()"
 Python 3.7.7 (default, Mar 10 2020, 15:43:03) 
 (InteractiveConsole)
 >>> import os; os.curdir
 '.'

Мне не нужно было просить распечатать '.'. Он просто сделал это.

Под крышкой видно, что это реализовано с помощью функции exe c ():

https://github.com/python/cpython/blob/800a35c623bbcdb5793c7d7a4974524286311479/Lib/code.py#L90

    try:
        exec(code, self.locals)
    except SystemExit:
        raise
    except:
        self.showtraceback()

Странно то, что здесь нет явной инструкции для вывода результата exe c (). И все же мы видим, что он выводит его.

Мы видим, что это поведение очень зависит от контекста c вот так: C code Я увижу, что он запрашивает свой контекст, чтобы узнать, выводить ли значение или нет. Но это не ответило бы на мой главный вопрос, а именно, как имитировать это поведение в произвольном контексте.

Как я могу выполнить и получить «псевдо-возвращаемое значение» из строки Python, независимо от того, представляет ли строка выражение или оператор?

1 Ответ

0 голосов
/ 29 мая 2020

Компилятор Python имеет флаг , чтобы отслеживать, выполняется ли Python в интерактивном режиме .

Если этот флаг установлен, когда компилятор посещает инструкцию узел в AST, он испускает дополнительный PRINT_EXPR код операции .

Интерпретатор выполняет PRINT_EXPR, выталкивая результат выражения из стека и передавая это как аргумент для sys.displayhook. Displayhook печатает repr этого значения в стандартный вывод, если значение не равно None. Он также присваивает значение builtins._.

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

Итак, пока вы работаете Python в интерактивном режиме, вы можете прочитать значение встроенной _ после запуска кода с помощью встроенной exec.

...