Pull to refresh

Перенаправление print() в файл с помощью Python

Всем привет!

С Python работаю совсем недавно. Многого не знаю. Заранее приношу свои извинения.

При разработке программ, для отслеживания логики выполнения и информировании при возникновении исключений, использую функцию print(), которая выводит данные на консоль. На мой взгляд это очень удобно: быстро вставил print('нужная_информация'). Но для использования модуля уже в работе принты, выводящие информацию на консоль совершенно лишние. Хотя конечно, некоторую информацию все таки хотелось бы логировать, писать в файл.

«Погуглил». На сегодняшний день в интернете на эту тему предлагаются решения, которые подразумевают вносить большие изменения в код программы, либо работающие не совсем так, как того хотелось бы.

Первое. Перенаправление stdout в файл — хорошо, но вывод в файл осуществляется только после закрытия файла. Недостатки: одновременно выводится большое количество информации, которая может быть утеряна при сбое; построчное сохранение в файл требует открытия и закрытия файла при каждом принте, а в код такие дополнения вносить не хотелось бы.

Второе. Предлагается использование специальных логгеров. Они конечно же удобные, умеют различать ошибки и варнинги, но так же требуют кардинальной переработки кода под себя.

Перерабатывать ни чего не хочется. Не хочется дописывать в принты дополнительные параметры для записи в файл, а хочется просто оставить так как есть, но что бы вывод осуществлялся не на консоль а в файл.

Решение нашел. Собственно суть написания статьи в том, что бы им поделиться, вдруг действительно кому то будет полезно.

Итак. Исходные данные:

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

Для решения этой задачи создадим класс, в который передадим параметры: имя лога и вывод на консоль или в файл и метод, который и будет осуществлять наш вывод либо туда (файл), либо сюда (консоль).

Класс выглядит так:

class mylogger(object):
	def __init__(self, fn='', tofile=False):
		self.fn = fn
		self.tofile = tofile
		return
	def printml(self, *args):
		toprint = ''
		for v in args:
			toprint = toprint + str(v) + ' '
		if self.tofile:
			f = open(self.fn, 'a')
			f.write(toprint + "\n")
			f.close()
		else: print(toprint)
		return

Теперь, для того, что бы все принты в скрипте выводили данные в файл в соответствии с описанными выше требованиями нужно добавить пару строк в начале модуля:

# создаем экземпляр объекта
# указываем имя лога и 
# PRINT_TO_FILE = True - вывод в файл, 
# иначе - на консоль
log = mylogger(LOGFILE, PRINT_TO_FILE)

# переопределяем адрес функции print()
# на адрес метода нашего логгера
print = log.printml

Все! В коде больше ни чего переделывать не нужно. Изменив параметр PRINT_TO_FILE мы теперь можем либо печатать на консоль, либо в фай.

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

Надеюсь материал будет полезен!

Всем успехов!
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.