Перевод публикуется с сокращениями, автор оригинальной статьи Khuyen Tran.
Мотивация
Если вы используете print для отладки кода, в терминале может оказаться множество строк вывода, а вам придется выяснять выяснить, к какому участку кода принадлежит конкретный вывод.
Например, запустив приведенный ниже скрипт…
num1 = 30 num2 = 40 print(num1) print(num2)
…мы получим следующее:
30 40
Какой из этих выводов является num1
, а какой num2
? Что делать, если будет более 5 переменных? Попытка найти отвечающий за вывод исходный код может занять много времени.
Для облегчения поиска можно добавить текст в объявлении печати:
num1 = 30 num2 = 40 print('num1', num1) print('num2', num2)
num1 30 num2 40
Вывод понимается легче, но он по-прежнему отнимает некоторое количество времени. Есть способ, который отвечает за вывод без дополнительного текста:
num1 = 30 num2 = 40 ic(num1) ic(num2)
ic| num1: 30 ic| num2: 40
Вот в чем прелесть использования Icecream.
Что такое Icecream?
Это библиотека Python, которая делает отладку печати более читабельной с минимальным количеством кода и поддерживающаяся в Python 2, Python 3, PyPy2 и PyPy3.
Для ее установки используется следующая команда:
$ pip install icecream
Попробуем напечатать вывод функции Python:
from icecream import ic def plus_five(num): return num + 5 ic(plus_five(4)) ic(plus_five(5))
Используя ic
, мы видим не только выходные данные, но и функцию с ее аргументами. Удобно! Цвет в терминале также будет таким же, как и показанный выше вывод.
Проверка выполнения
Определить где был выполнен код можно следующим образом:
def hello(user:bool): if user: print("I'm user") else: print("I'm not user") hello(user=True)
I'm user
С Icecream задача решается простым вызовом ic()
без дополнительных параметров:
from icecream import ic def hello(user:bool): if user: ic() else: ic() hello(user=True)
Становится понятно, что код в строке 5 из функции hello
был выполнен, а код в строке 7 не работал.
Кастомный префикс
Если хотите вставить кастомный префикс в свой оператор печати, например, время выполнения кода, Icecream позволит сделать и это:
from datetime import datetime from icecream import ic import time def time_format(): return f'{datetime.now()}|> ' ic.configureOutput(prefix=time_format) for _ in range(3): time.sleep(1) ic('Hello')
Теперь время выполнения кода автоматически отображается в выходных данных.
Получаем больше контекста
Помимо информации об отвечающем за вывод коде можно узнать, из какой строки и файла был он был выполнен. Чтобы это реализовать и узнать контекст, добавьте includeContext=True
в ic.configureOutput()
:
from icecream import ic def plus_five(num): return num + 5 ic.configureOutput(includeContext=True) ic(plus_five(4)) ic(plus_five(5))
Первый вывод был выполнен функцией plus_five
из файла icecream_example.py
в строке 7.
Удаляем Icecream после завершения отладки
Icecream можно использовать не только для отладки, но и, например, для красивой печати:
from icecream import ic def plus_five(num): return num + 5 ic(plus_five(4)) ic(plus_five(5)) for i in range(10): print(f'****** Training model {i} ******')
Поскольку теперь можно различить отладочный и красивый вывод, становится проще искать и удалять все операторы ic после отладки:
После удаления всех отладочных следов код остается чистым.
Заключение
Поскольку обнаружение, локализация и устранение ошибок очень важны в разработке, необходимо стараться делать этот этап проще и понятнее. Мы изучили, как сделать вывод отладочной информации на экран более читабельным и информативным с помощью Icecream. Существует масса других вариантов: django-debug-toolbar, py-spy, line_profiler, memory_profiler и т. д. но описанный в статье легковеснее и практичнее.
Дополнительные материалы:
10 классных функций Python 3.9
Сложность алгоритмов и операций на примере Python
29 Python-проектов, оказавших огромное влияние на разработку
Реализация элементарных абстрактных типов данных в Python
ТОП-10 книг по Python: эффективно, емко, доходчиво