Как перенаправить как файл кода, так и вывод терминала в один и тот же выходной файл (имитирующий python repl)?

Я хотел бы сохранить входной код и результат вывода в файл. Например, следующий код Python code.py:

print(2+2)
print(3+2)

чтобы создать code-and-output.txt:

>>> print(2+2)
4
>>> print(3+2)
5

Но я не могу заставить его работать. По сути, я хочу code-and-output.txt зафиксировать, что произойдет, если я запущу интерпретируемый python и запущу операторы в интерактивной среде python (код + вывод). Способы, которые я пробовал до сих пор:

Перенаправить стандартный вывод:

python code.py > code-and-output.txt Он сохраняет только вывод.

Перенаправить стандартный вывод и стандартный ввод:

python < code.py > code-and-output.txt Он делает то же самое (только вывод).

нет

nohup python code.py Та же проблема: только вывод.

Скрипт

script -q code-and-output.txt
python
print(2+2)
print(2+3)
ctr+d
ctr+d

Это работает, но мне нужно сделать это вручную. Более того, это спасает какой-то мусор, который я не могу заставить их замолчать с помощью -q.

Баш-скрипт

# bash-file.sh
python &
print(2+2)
print(2+3)

Не работает: команды запускаются в консольном bash, а не в python. Это также не работает с &: никогда не заканчивается python repl.

Использование телетайпа

откройте другой терминал, например /dev/pts/2, и отправьте выше bash-file.sh

cat bash-file.sh > /dev/pts/2

Просто копирует, но не запускается.

Меня не интересуют такие решения, как Jupyter и iPython. У них есть свои проблемы, которые не соответствуют моему требованию.

Любое решение с помощью команд Linux (предпочтительно) или Python? Спасибо.

см. этот ответ для перенаправления вывода, но вкратце: SomeCommand 2>&1 | tee SomeFile.txt

Edo Akse 19.03.2022 00:25

Он создает точно такой же вывод, как и в python code.py > output.txt: он не включает сам код. Проблема в том, что python code.py имеет другой результат, чем запуск кода внутри интерактивного терминала Python.

Ali Khosro 19.03.2022 00:33

Я неправильно понял ваш вопрос, извините. Можете ли вы привести другой пример? Первый code-and-output.txt на самом деле не соответствует вводу, который вы упомянули выше. Вы хотите, чтобы ввод и вывод интерактивного интерпретатора Python полностью перехватывались?

Edo Akse 19.03.2022 01:04

Да, точно. Чтобы зафиксировать в файле, что произойдет, если я сделаю это вручную: ``` python >>> print(2+2) 4 >>>print(2+3) 5 >>>exit() ``` Проблема в том, что python code.py печатает только вывод.

Ali Khosro 19.03.2022 01:09

да, потому что код внутри code.py на самом деле нигде не печатается, он интерпретируется. Между ними есть большая разница. Я думаю, что то, чего вы хотите достичь, нелегко. Насколько я могу судить, вам нужно будет создать свой собственный интерпретатор.

Edo Akse 19.03.2022 01:17
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
30
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Сохраните это как repl_sim.py в том же каталоге, что и ваш code.py:

with open("code.py", 'r') as input_file:
    for line in input_file:
        print(f">>> {line.strip()}")
        eval(line)

Затем запустите в своем терминале следующее, если вы хотите перенаправить вывод в текстовый файл с именем code-and-output.txt:

python repl_sim.py > code-and-output.txt

-ИЛИ-

Затем запустите в своем терминале следующее, если вы хотите увидеть вывод, а также сделать соответствие текстового файла:

python repl_sim.py  | tee code-and-output.txt

По крайней мере, это работает для примера, который вы указали как code.py.


Чистая версия Python первого варианта выше, так что вам не нужно перенаправление оболочки.
Сохраните этот код как repl_sim.py:

import contextlib
with open('code-and-output.txt', 'w') as f:
    with contextlib.redirect_stdout(f):
        with open("code.py", 'r') as input_file:
            for line in input_file:
                print(f">>> {line.strip()}")
                eval(line)

Затем запустите в своем терминале:

python repl_sim.py

Это приведет к code-and-output.txt желаемому контенту.

Использование Contextlib на основе Твит Рэймонда Хеттингера от 17 августа 2018 г. и документация contextlib.redirect_stdout() .

Другие вопросы по теме