Как распечатать консоль в текстовый файл ПОСЛЕ завершения программы (Python)?
У меня есть программа, которая выводит множество вычислений и результатов на консоль через оператор печати. Я хочу написать код для экспорта (или сохранения) всего содержимого консоли в простой текстовый файл.
Я искал StackOverflow и другие сайты, но нашел некоторые методы для перенаправления оператора печати для печати в файл напрямую, но я хочу, чтобы программа работала нормально, отображая выходы на консоль, а затем сохраняя ее содержимое ПОСЛЕ всех операций выполненной программы.
Я использую PyCharm с Python2.7, если это важно
Ответы
Ответ 1
Со всей благодарностью и уважением ко всем, кто внес свой вклад в этот вопрос. Я, наконец, нашел решение этой проблемы с минимальными изменениями в моем исходном коде. Решение предоставляется членом @Status, и вот его ссылка.
Хотя я много искал, прежде чем публиковать свой вопрос, но ответы уважаемых членов озарили мой взгляд на точный поиск, особенно вклад @turkus, который выполняет исключительную работу, и @Glostas, который открыл глаза на "тройник", который посоветовал мне найти решение, которое я разместил (хотя он не содержит "тройник").
Решение, как упоминалось выше, с небольшими изменениями:
1- Поместите в программу следующий класс:
class Logger(object):
"""
Lumberjack class - duplicates sys.stdout to a log file and it okay
source: /questions/49207/how-do-i-duplicate-sysstdout-to-a-log-file-in-python/348798#348798
"""
def __init__(self, filename="Red.Wood", mode="a", buff=0):
self.stdout = sys.stdout
self.file = open(filename, mode, buff)
sys.stdout = self
def __del__(self):
self.close()
def __enter__(self):
pass
def __exit__(self, *args):
pass
def write(self, message):
self.stdout.write(message)
self.file.write(message)
def flush(self):
self.stdout.flush()
self.file.flush()
os.fsync(self.file.fileno())
def close(self):
if self.stdout != None:
sys.stdout = self.stdout
self.stdout = None
if self.file != None:
self.file.close()
self.file = None
2- В начале программы перед любыми заявлениями печати поместите эту строку:
my_console = Logger('my_console_file.txt') # you can change the file name
3- В конце программы, после всех операторов печати, введите следующую строку:
my_console.close()
Я тестировал это, и он отлично работает, и, наконец, у меня есть клон выхода консоли после завершения программы.
С наилучшими пожеланиями всем, и большое спасибо всем участникам.
Ответ 2
Хорошо, поэтому, чтобы это сделать, вам нужно переписать встроенную функцию python print
. Но... Есть ipython, который предоставляет некоторые крючки.
Сначала вам нужно установить ipython
:
#bash
sudo pip install ipython
(Я использую sudo для простого поиска, затем папку, которую мне нужно достичь, читайте далее)
После установки ipython у вас будет доступная папка расширения ipython, поэтому перейдите к ней:
#bash
cd ~/.ipython/extensions/
и создайте там пусть скажем файл с именем print_to_file.py
, вот его содержимое:
#python
class PrintWatcher(object):
def __init__(self, ip):
self.shell = ip
def post_execute(self):
with open('/home/turkus/shell.txt', 'a+') as f:
in_len = len(self.shell.user_ns['In'])
i = in_len - 1
in_ = self.shell.user_ns['In'][i]
out = self.shell.user_ns['Out'].get(i, '')
# you can edit this line if you want different input in shell.txt
f.write('{}\n{}\n'.format(in_, out))
def load_ipython_extension(ip):
pw = PrintWatcher(ip)
ip.events.register('post_run_cell', pw.post_execute)
После сохранения только запускаемого файла:
#bash
ipython profile create
# you will get something like that:
[ProfileCreate] Generating default config file: u'/home/turkus/.ipython/profile_default/ipython_config.py'
Теперь вернемся к настройке нашего крючка. Мы должны открыть ipython_config.py
, созданный по пути выше, и поместить туда какую-нибудь магию (там много чего, так что идите в конец файла):
# some commented lines here
c = get_config()
c.InteractiveShellApp.extensions = [
'print_to_file'
]
После сохранения его можно запустить ipython
и написать свой код. Каждый ваш вход будет записан в файл по пути, указанному выше, в моем случае это было:
/home/turkus/shell.txt
Примечания
Вы можете избежать загрузки расширения каждый раз, когда запускается ipython
, просто удалите 'print_to_file'
из c.InteractiveShellApp.extensions
в списке ipython_config.py
. Но помните, что вы можете загрузить его в любое удобное для вас время, просто набрав консоль ipython
:
➜ ~ ipython
Python 2.7.12 (default, Jul 1 2016, 15:12:24)
Type "copyright", "credits" or "license" for more information.
IPython 4.0.0 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython features.
%quickref -> Quick reference.
help -> Python own help system.
object? -> Details about 'object', use 'object??' for extra details.
In [1]: %load_ext print_to_file
Любое изменение в print_to_file.py
отражается в открытой оболочке ipython после использования команды %reload_ext print_to_file
, поэтому вам не нужно выходить из нее и запускать ее снова.
Ответ 3
Я не уверен, как вы могли получать содержимое консоли для любого редактора, но этого можно добиться достаточно просто, заменив операторы print()
на .write
class Writer(object):
def __init__(self, out_file, overwrite=False):
self.file_name = out_file
self.overwrite = overwrite
self.history = []
def write(self, statement):
self.history.append(statement)
print statement
def close(self):
if self.overwrite:
self.out_file = open(self.file_name, 'wb')
else:
self.out_file = open(self.file_name, 'ab')
for x in self.history:
self.out_file.write(x+'/n')
self.out_file.close()
self.history = []
p = Writer('my_output_file.txt')
p.write('my string to print and save!')
p.close() #close the writer to save the contents to a file before exiting
Ответ 4
После того, как я понял, понял ваш вопрос, я думаю, что вы ищете команду tee
python your_program | tee output.txt
Это покажет вам выход как в консоли, так и в файле output.txt
PS: Поскольку вы не ответили на мой комментарий, какую ОС используете, я предположил, что вы используете Linux или MACOS. Должен работать на обоих. Я не знаю, как это сделать на окнах...
Ответ 5
Вы можете переопределить функцию print
, которая по-прежнему будет доступна через модуль builtins
import builtins
f = open("logs.txt", "w")
def print(*args, sep=' ', end='\n', **kwargs):
builtins.print(*args, sep=sep, end=end, **kwargs)
f.write(sep.join(*args) + end)
EDIT: аналогичное решение для Python 2
from __future__ import print_function
class Print:
def __init__(self, print_function, filename='test', mode='w'):
self.print_function = print_function
self.file = open(filename, 'w')
def __call__(self, *args, **kwargs):
self.print_function(*args, **kwargs)
kwargs['file'] = self.file
self.print_function(*args, **kwargs)
print = Print(print, 'logs.txt')
Это создает функцию print
, которую вы используете точно так же, как функция, которую вы импортируете из __future__
.
Чтобы закрыть файл, когда все будет сделано, вам нужно запустить:
print.file.close()
Ответ 6
Возможно, вам следует создать переменную, которая будет регистрировать выходы, а затем помещать их в файл.
Для ex:
print statement
logger += statement+"\n" #a new line char so each statement is on a new line
with open('file.txt', 'a') as f:
f.write(statement)
Ответ 7
Существует очень очевидное, но не очень элегантное решение.
вместо:
print statement 1
calculation
print statement 2
вы можете сделать что-то вроде
sexport =''
calculation
print statement 1
sexport += statement1 + "\n"
calculaztion
print statement 2
sexport += statement 2
наконец-то просто спасите sexport в файл