Вопрос: какую из стандартных функций Python разработчики используют чаще всего? Наверняка, как и в большинстве языков программирования, ответом будет функция print()
: во время разработки трудно удержаться от многократного вывода сообщений в консоль.
Конечно, не существует альтернативы, способной полностью заменить функцию print()
. Однако для вывода отладочных сообщений в консоль лучше использовать другие инструменты. Например, в статье представлена интересная сторонняя библиотека Python под названием “IceCream”: с её помощью вы откроете для себя множество удобств быстрой и простой отладки программного кода.
Плохой пример
Начнем с относительно плохого примера. Предположим, что определена функция square_of
, и мы хотим проверить, работает ли она согласно ожиданиям.
def square_of(num):
return num*num
Вышеописанная функция банально возвращает квадрат числа, переданного в качестве аргумента. Проверим её пару раз:
print(square_of(2))
print(square_of(3))
print(square_of(4))
Пока функция одна, тем более такая простая, подобный подход к отладке программного кода удовлетворяет всем потребностям. Однако те функции, с чьей отладкой придется встретиться на практике, состоят из гораздо большего количества строк кода. Кроме того, часто встречается необходимость множественного вызова функции print()
для абсолютно разных значений: в таком случае легко запутаться, какой вывод генерируется той или иной функцией print()
.
print('square of 2:', square_of(2))
print('square of 3:', square_of(3))
print('square of 4:', square_of(4))
Теперь пример стал немного лучше, но каждый раз вручную прописывать пояснительные строки — слишком утомительно. Более того, после окончания разработки, скорее всего, вам придется удалить почти все отладочные сообщения.
Проверка переменных
Обратим внимание на Python-библиотеку под названием “Ice Cream” и ответим на вопрос: как она решает проблемы, о которых говорилось выше?
Прежде всего, необходимо установить библиотеку из репозитория PyPI с помощью пакетного менеджера pip
(или любого другого):
pip install icecream
Перед использованием библиотеки — импортируем её в программу:
from icecream import ic
Вследствие чего появляется возможность гораздо удобнее выводить отладочную информацию в консоль.
Вызов функции
Библиотеку icecream
можно использовать напрямую для вывода возвращаемых функцией значений в консоль, точно так же, как ранее использовалась функция print()
.
ic(square_of(2))
ic(square_of(3))
ic(square_of(4))
Отлично! Несмотря на то, что не указано ни одного отладочного сообщения для вызова функции ic()
, она все равно выводит на экран имя функции, ее аргументы и результат выполнения. Таким образом, нам больше не нужно вручную добавлять “краткое описание”.
Доступ к словарю
Кроме обычного вызова функции, похожего на print()
, библиотека icecream
способна выводить всю необходимую информацию в удобном для чтения виде, ускоряя и облегчая отладку, например при обращении к паре ключ-значение в словаре.
my_dict = {
'name': 'Chris',
'age': 33
}
ic(my_dict['name'])
В примере определен словарь, и необходимо реализовать доступ к его значению по ключу. При использовании библиотеки icecream
в консоль выводится и значение словаря, и ключ, к которому выполнялось обращение.
Доступ к атрибутам объекта
В качестве еще одного примера, давайте определим класс и создадим для него объект-экземпляр:
class Dog():
num_legs = 4
tail = True
dog = Dog()
Вывод в консоль значения атрибута объекта-экземпляра класса Dog
с помощью библиотеки icecream
:
ic(dog.tail)
Отладка условия if
Библиотека icecream
упрощает проверку не только переменных, но и управляющих конструкций, таких как условие if
. Например, рассмотрим простое условие:
input = 'Chris'
if input == 'Chris':
ic()
else:
ic()
Для начала разместим вызов функции icecream
в блоках if
и else
. Посмотрим, что произойдет:
Хотя в коде программы оператор условия if-else
буквально ничего не делает, функция ic()
выводит в консоль номер строки, где она была вызвана, и время вызова.
Пример демонстрируется в Jupyter Notebook, но при запуске функции ic()
из файла в формате .py
, кроме номера строки и времени запуска вы также получите имя файла, из которого произошел вызов.
Рассмотрим более практичный случай использования функции ic()
из Python-библиотеки icecream
:
def check_user(username):
if username == 'Chris':
# Делается что-либо
ic()
else:
# Делается что-либо еще
ic()
check_user('Chris')
check_user('Jade')
При вызове функция check_user()
подействует в зависимости от значения аргумента username
. Допустим, в целях отладки важно знать, кто именно является текущим пользователем. Функция ic()
как раз сообщает нам это:
Вставка в существующий код
Далее обсудим одну интересную особенность библиотеки icecream
: функция ic()
не только выводит подробную информацию в консоль, но и передает значение таким образом, что оно может использоваться в качестве функции-обертки для всего что угодно. Другими словами, функция ic()
способна обернуть в себя любой объект, не затрагивая создавая последствий.
Давайте рассмотрим новый функционал библиотеки icecream
на примере все той же функции sqaure_of()
, определенной в предыдущем разделе статьи.
num = 2
square_of_num = square_of(ic(num))
В примере определена переменная num
, и нам нужно вычислить ее квадрат с помощью вызова функции square_of()
. Вместо square_of(num)
в примере выше функция ic()
оборачивает саму переменную num
. Таким образом, консольный вывод будет состоять не из результата работы функции square_of(num)
, присвоенного переменной square_of_num
, а только из значения самой переменной num
.
А вот протестировать результат из переменной square_of_num
можно следующим образом:
Как видно, square_of_num
равна квадрату переменной num
. Кроме того, в данном if
-условии не только функция ic()
используется без влияния на результат, но и переменная square_of_num
все равно выводится для отладки!
Отключение библиотеки icecream
Одна из больших проблем использования функции print()
в отладочных целях заключается в том, что сообщений слишком много. Кроме того, они часто остаются повсюду после завершения разработки. В таком случае желание быстро очистить код от отладочных сообщений, написанных с помощью функции print()
, приведет к настоящей катастрофе.
А вот в случае использования отладочной библиотеки icecream
, все, что нам нужно сделать, — это просто отключить ее!
ic.disable()
После выполнения метода ic.disable()
все функции ic()
, из любого места в коде программы, перестанут что-либо выводить в консоль. Например, приведенный ниже код ничего не выведет:
Тем не менее следует задаться вопросом: как насчет переменной square_of_num
? Будет ли она по-прежнему передаваться после отключения библиотеки icecream
? Не волнуйтесь, ic.disable()
отключает исключительно вывод текста в консоль, не нужно беспокоиться о работоспособности обернутых в ic()
функций.
if ic(square_of_num) == pow(num, 2):
print('Correct!')
При замене консольного вывода обратно на функцию print()
, программа все равно будет работать. Получается, что ic(square_of_num)
по-прежнему эквивалентно square_of_num
:
Конечно, снова понадобится вернуться в режим отладки, icecream
очень легко включается обратно:
ic.enable()
Настройка отладочных сообщений
Библиотека icecream
реализовывает тонкую настройку и форматирование сообщений. Самой популярной настройкой считается изменение префикса. Вы, наверное, заметили, что вывод отладочных сообщений по умолчанию всегда начинается с префикса ic |
. Это можно изменить.
Например, ввиду отладочной цели хорошей идеей будет указать слово Debug
в качестве префикса:
ic.configureOutput(prefix='Debug | ')
ic('test')
Более того, в качестве префикса можно указывать не только статические строки, но и функции. Например, определим функцию, возвращаемое значение которой является текущей временной меткой в виде форматированной строки.
from datetime import datetime
def now():
return f'[{datetime.now()}] '
Затем установим полученную функцию now()
в качестве префикса отладочных сообщений icecream
:
ic.configureOutput(prefix=now)
ic('test')
Выводы
В статье представлена замечательная сторонняя Python-библиотека под названием “Ice Cream”. Она улучшает функцию print()
, детализируя ее и повышая удобство отладки программ на Python.
Библиотека icecream
никогда не заменит стандартную функцию print()
, потому что у них разные цели, а также систему протоколирования. Она скорее находится где-то между этими двумя инструментами.
Жизнь коротка, используйте Python!
Читайте также:
- 9 важных сниппетов Python для оптимизации работы со скриптами
- Как писать код на Python лучше: 6 рекомендаций
- Python Django: как изменить страницу ошибки 404?
Читайте нас в Telegram, VK и Яндекс.Дзен
Перевод статьи Christopher Tao: Do Not Use Print For Debugging In Python Anymore