При разработке программ, для отслеживания логики выполнения и информировании при возникновении исключений, использую функцию print(), которая выводит данные на консоль. На мой взгляд это очень удобно: быстро вставил print(‘нужная_информация’). Но для использования модуля уже в работе принты, выводящие информацию на консоль совершенно лишние. Хотя конечно, некоторую информацию все таки хотелось бы логировать, писать в файл.
«Погуглил». На сегодняшний день в интернете на эту тему предлагаются решения, которые подразумевают вносить большие изменения в код программы, либо работающие не совсем так, как того хотелось бы.
РЕКОМЕНДУЕМ:
Система распознавания лиц на Python
Первое. Перенаправление stdout в файл — хорошо, но вывод в файл осуществляется только после закрытия файла. Недостатки: одновременно выводится большое количество информации, которая может быть утеряна при сбое; построчное сохранение в файл требует открытия и закрытия файла при каждом принте, а в код такие дополнения вносить не хотелось бы.
Второе. Предлагается использование специальных логгеров. Они конечно же удобные, умеют различать ошибки и варнинги, но так же требуют кардинальной переработки кода под себя.
Перерабатывать ни чего не хочется. Не хочется дописывать в принты дополнительные параметры для записи в файл, а хочется просто оставить так как есть, но что бы вывод осуществлялся не на консоль а в файл.
Решение нашел. Собственно суть написания статьи в том, что бы им поделиться, вдруг действительно кому то будет полезно.
Итак. Исходные данные:
- много кода;
- много принтов в коде;
- хочется их выводить не на консоль, а логировать в файл;
- но иногда нужно снова все видеть на консоли а не в файле;
- желательно, что бы это делалось построчно, а не крупными блоками;
- вносить много изменений в код совершенно не хочется.
Для решения этой задачи создадим класс, в который передадим параметры: имя лога и вывод на консоль или в файл и метод, который и будет осуществлять наш вывод либо туда (файл), либо сюда (консоль).
Класс выглядит так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
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 |
Теперь, для того, что бы все принты в скрипте выводили данные в файл в соответствии с описанными выше требованиями нужно добавить пару строк в начале модуля:
1 2 3 4 5 6 7 8 9 |
# создаем экземпляр объекта # указываем имя лога и # PRINT_TO_FILE = True - вывод в файл, # иначе - на консоль log = mylogger(LOGFILE, PRINT_TO_FILE) # переопределяем адрес функции print() # на адрес метода нашего логгера print = log.printml |
Все! В коде больше ни чего переделывать не нужно. Изменив параметр PRINT_TO_FILE мы теперь можем либо печатать на консоль, либо в фай.
Если есть необходимость логировать многопоточное выполнение скриптов, то можно просто немного изменить класс, для вывода не построчно, а блоками для каждого потока. В общем, это уже по необходимости.
РЕКОМЕНДУЕМ:
Как сделать свою структуру данных в Python совместимой с фичами
Надеюсь материал будет полезен! Всем успехов!