Реализация логирования
На этом этапе мы сделаем ваш код лучше. Вместо простых сообщений print
мы будем использовать модуль logging
Python для правильного логирования. Логирование - это отличный способ отслеживать, что делает ваша программа, особенно когда дело доходит до обработки ошибок и понимания потока выполнения кода.
Понимание модуля логирования
Модуль logging
в Python предоставляет гибкий способ отправки лог - сообщений из наших приложений. Он намного мощнее, чем просто использование простых инструкций print
. Вот, что он может делать:
- Различные уровни логирования (DEBUG, INFO, WARNING, ERROR, CRITICAL): Эти уровни помогают нам классифицировать важность сообщений. Например, DEBUG используется для детальной информации, полезной во время разработки, в то время как CRITICAL - для серьезных ошибок, которые могут остановить программу.
- Настраиваемый формат вывода: Мы можем решить, как будут выглядеть лог - сообщения, например, добавить временные метки или другую полезную информацию.
- Сообщения могут быть направлены на разные выходы (консоль, файлы и т.д.): Мы можем выбрать показывать лог - сообщения на консоли, сохранять их в файл или даже отправлять на удаленный сервер.
- Фильтрация логов по серьезности: Мы можем контролировать, какие сообщения мы видим, основываясь на их уровне логирования.
Добавление логирования в reader.py
Теперь давайте изменим ваш код, чтобы использовать модуль логирования. Откройте файл reader.py
.
Сначала нам нужно импортировать модуль logging
и настроить логгер для этого модуля. Добавьте следующий код в начало файла:
import logging
## Set up a logger for this module
logger = logging.getLogger(__name__)
Инструкция import logging
импортирует модуль logging
, чтобы мы могли использовать его функции. logging.getLogger(__name__)
создает логгер для этого конкретного модуля. Использование __name__
гарантирует, что логгер имеет уникальное имя, связанное с модулем.
Далее мы изменим функцию convert_csv()
для использования логирования вместо инструкций print
. Вот обновленный код:
def convert_csv(rows, converter, header=True):
"""
Convert a sequence of rows to an output sequence according to a conversion function.
"""
if header:
headers = next(rows)
else:
headers = []
result = []
for row_idx, row in enumerate(rows, start=1):
try:
## Try to convert the row
result.append(converter(headers, row))
except Exception as e:
## Log a warning message for bad rows
logger.warning(f"Row {row_idx}: Bad row: {row}")
## Log the reason at debug level
logger.debug(f"Row {row_idx}: Reason: {str(e)}")
continue
return result
Основные изменения здесь следующие:
- Мы заменили
print()
на logger.warning()
для сообщения об ошибке. Таким образом, сообщение логируется с соответствующим уровнем предупреждения, и мы можем контролировать его видимость позже.
- Мы добавили новое сообщение
logger.debug()
с деталями об исключении. Это дает нам больше информации о том, что пошло не так, но оно показывается только если уровень логирования установлен на DEBUG или ниже.
str(e)
преобразует исключение в строку, чтобы мы могли отобразить причину ошибки в лог - сообщении.
После внесения этих изменений сохраните файл.
Тестирование логирования
Давайте протестируем ваш код с включенным логированием. Откройте интерпретатор Python, выполнив следующую команду в терминале:
python3
После того, как вы находитесь в интерпретаторе Python, выполните следующий код:
import logging
import reader
## Configure logging level to see all messages
logging.basicConfig(level=logging.DEBUG)
port = reader.read_csv_as_dicts('missing.csv', types=[str, int, float])
print(f"Number of valid rows processed: {len(port)}")
Здесь мы сначала импортируем модуль logging
и наш модуль reader
. Затем мы устанавливаем уровень логирования на DEBUG с помощью logging.basicConfig(level = logging.DEBUG)
. Это означает, что мы увидим все лог - сообщения, включая DEBUG, INFO, WARNING, ERROR и CRITICAL. Затем мы вызываем функцию read_csv_as_dicts
из модуля reader
и выводим количество обработанных корректных строк.
Вы должны увидеть вывод, похожий на следующий:
WARNING:reader:Row 4: Bad row: ['C', '', '53.08']
DEBUG:reader:Row 4: Reason: invalid literal for int() with base 10: ''
WARNING:reader:Row 7: Bad row: ['DIS', '50', 'N/A']
DEBUG:reader:Row 7: Reason: could not convert string to float: 'N/A'
...
Number of valid rows processed: 20
Обратите внимание, что модуль логирования добавляет префикс к каждому сообщению, показывая уровень логирования (WARNING/DEBUG) и имя модуля.
Теперь давайте посмотрим, что произойдет, если мы изменим уровень логирования так, чтобы показывать только предупреждения. Выполните следующий код в интерпретаторе Python:
## Reset the logging configuration
import logging
logging.basicConfig(level=logging.WARNING)
port = reader.read_csv_as_dicts('missing.csv', types=[str, int, float])
На этот раз мы устанавливаем уровень логирования на WARNING с помощью logging.basicConfig(level = logging.WARNING)
. Теперь вы увидите только сообщения WARNING, а сообщения DEBUG будут скрыты:
WARNING:reader:Row 4: Bad row: ['C', '', '53.08']
WARNING:reader:Row 7: Bad row: ['DIS', '50', 'N/A']
...
Это показывает преимущество использования разных уровней логирования. Мы можем контролировать, сколько деталей показывается в логах, не изменяя наш код.
Чтобы выйти из интерпретатора Python, выполните следующую команду:
exit()
Поздравляем! Теперь вы реализовали правильную обработку исключений и логирование в своей программе на Python. Это делает ваш код более надежным и дает вам лучшую информацию при возникновении ошибок.