Найти в Дзене
Nuances of programming

Не слушай профи - делай print()

Оглавление

Источник: Nuances of Programming

Если вы скажете профессиональным программистам, что используете print() для отслеживания ошибок, готовьтесь уворачиваться от летящих в вашу сторону стульев. Есть ли смысл продираться через дебри трассировки стека с полной настройкой отладки, будучи новичком? Некоторые скажут “да”, поскольку они изначально научились это делать. Я же утверждаю: “Любые средства хороши  —  был бы результат”.

Это совсем не значит, что вам не нужно учиться распознавать ошибки  —  речь о другом. Когда вы программируете в свое удовольствие или намереваетесь создать для кого-либо небольшие фрагменты кода, так ли необходимо проводить отладку на профессиональном уровне? Если вы занимаетесь программированием себе на радость и в свободное время, то вряд ли вам потребуется проводить “образцовую” отладку на протяжении всей вашей карьеры разработчика.

В большинстве случаев коду рано или поздно потребуется отладка. К счастью, существует несколько способов ее осуществить, не прибегая к полному каноническому варианту разработчика.

Прежде всего посмотрим, как функция print() может помочь в отладке кода.

print()

print() обеспечит мгновенное визуальное воплощение того, над чем вы работаете. Если вы ожидаете вполне определенный результат, то сразу же увидите его в терминале. Если он верный  —  смело продолжайте работу. Если нет  —  ищите причину.

Рассмотрим пример с применением print():

greek_gods = ['Zeus','Poseidon','Apollo','Bob']
greek_gods_only = [god for god in greek_gods if god!='Bob']
gods = ','.join(greek_gods_only)

Как узнать, удалось ли изгнать Боба (Bob) из стана богов?

print(gods)

Боб покинул Олимп
Боб покинул Олимп

А теперь, когда Боб вернулся с небес на землю, можно рассмотреть пример из реальной практики.

Не так давно я разработал инструмент в Autodesk Maya для управления камерами. В анимационной сцене мне потребовалось составить список всех камер съемки, исключив камеры, используемые в этом редакторе по умолчанию. К счастью для нас, в Maya они уже определены (startupCamera = True), поэтому их легко найти.

Камеры съемки лица
Камеры съемки лица

Как видите, первые три позиции в списке по-прежнему занимают ненужные камеры из каких-то ссылочных файлов. Теперь, воочию столкнувшись с этой ошибкой, я могу ее устранить, добавив and ‘face’ not in cam:

Прекрасно!
Прекрасно!

Не примени я функцию print для проверки вывода, пришлось бы пропускать код через конвейер. Вернулось бы сообщение об ошибке, и мы бы потратили время на ее обнаружение. А ошибка-то не очевидная, поскольку относится к разряду логических, а не тех, что останавливают выполнение кода.

Вывод данных с помощью print бережет наши деньги!

Альтернативные варианты отладки

Итак, вы, несомненно, хотите узнать доступные вам альтернативы отладки. С удовольствием используя print, вы понимаете, что неплохо бы расширить диапазон возможностей и пополнить “оружием” свой арсенал.

Рассмотрим ряд дополнительных способов отладки кода. Надеюсь, какой-нибудь из них придется вам по душе (или вы просто продолжите работать с print).

Python Tutor

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

Возьмем, к примеру, очень продвинутую функцию. Добавим код и кликнем на Visualize Execution (визуализация выполнения).

-5

После этого вы сможете работать с кодом, переходя от одной строки к другой. Код находится с левой стороны, а вывод данных  —  справа.

В следующем примере показан заключительный этап программы (шаг 9). В строке 4 происходит выполнение sum_input(10,10), и справа мы видим функцию и значение, которое она возвращает.

Python Tutor  —  это быстрый и наглядный способ проверить код.
Python Tutor  —  это быстрый и наглядный способ проверить код.

Assert

“Assert  —  это просто логическое выражение, которое проверяет, возвращают ли условия true или false. Если значение верно, то программа никак не реагирует и переходит к следующей строке кода. Однако, если оно ложно, то программа останавливается и выбрасывает ошибку” [Источник programiz].

Перед вами простой пример использования assert:

def sum_input(input_a, input_b):
return input_a + input_b

assert sum_input(2,3) == 5
assert sum_input(2,3) != 5

AssertionError показывает, что 2+3 на самом деле равняется 5.
AssertionError показывает, что 2+3 на самом деле равняется 5.

С помощью assert можно проверить, соответствует ли выполнение кода ожиданиям. В вышеуказанном примере вы ждете возврата значения 5, поэтому используете этот код, который возвращает True.

assert sum_input(2,3) == 5

А есть и такой код:

assert sum_input(2,3) != 5

2 + 3 в результате всегда дает только 5, следовательно вы ожидаете ошибку, которую и получаете. Измените код следующим образом assert sum_input(2,3) != 6 или укажите любое число кроме 5, и у вас не будет ошибок.

Поскольку именно вы инициируете эти ошибки, то их отсутствие было бы странным. Хотите почистить код  —  воспользуйтесь вот этим вариантом:

def sum_input(input_a, input_b):
return input_a + input_bassert sum_input(2,3) == 5
assert sum_input(2,3) != 6

Сам Усейн Болт мог бы позавидовать скорости выполнения программы
Сам Усейн Болт мог бы позавидовать скорости выполнения программы

Можете создать свои собственные сообщения об ошибках:

assert sum_input(2,3) != 5, '2+3 is 5...Stop this nonsense'

Thonny

Не так давно состоялось мое первое знакомство с Thonny, и она не оставила мне выбора  —  я влюбился. Это простая IDE со встроенным отладчиком, который показывает все, что происходит в коде. Среда на удивление простая, а возможности отладки превосходят все ожидания.

Рассмотрим следующий пример кода: программа проверяет все файлы, находящиеся в той же папке, что и программа Python. Затем она возвращает список с кортежем: (‘filename’, ‘extension’).

Thonny проинформирует вас о том, всё ли в порядке с вашим кодом. Ниже мы видим выполнение этого кода и возвращаемые им результаты:

Редактор кода, оболочка, помощник
Редактор кода, оболочка, помощник
Успешный возврат имен файлов и расширений в папку
Успешный возврат имен файлов и расширений в папку

Если намеренно добавить ошибку, например переименовать search_path в searchc_path, то среагирует Помощник:

Клик по ссылке в строке 8 в Помощнике выделяет ошибку
Клик по ссылке в строке 8 в Помощнике выделяет ошибку

Помощник также снабжает нас подсказками, облегчая процесс поиска и устранения ошибок. Если мы развернем вопрос “Did you misspell it (somewhere)?”, в котором он интересуется, а правильно ли было написано имя, то Thonny покажет нам похожие варианты имен и станет очевидно, где была допущена ошибка.

Благодарю тебя, Помощник. Теперь я знаю, где ошибка.
Благодарю тебя, Помощник. Теперь я знаю, где ошибка.

Если вы запускаете режим отладки, то Thonny пошагово выполнит код и покажет все, что в нем происходит:

Он останавливается на строке 24 с инструкцией if.

Выделение области
Выделение области
Позволяет нам узнать условие инструкции if
Позволяет нам узнать условие инструкции if
Обратим внимание на __name__
Обратим внимание на __name__
-16

pdb  —  встроенный отладчик Python

Если же вы предпочитаете работать в терминале, то Python оснащен встроенным отладчиком, известным как pdb. Благодаря ему вам не приходится повсюду в коде применять функции print(). Помимо этого, вы можете проверять функции и переменные и тестировать код в реальном режиме без редактирования его исходного варианта. Используя данный способ отладки, вы не ломаете код только из-за необходимости протестировать те или иные случаи.

Просто добавив в код breakpoint(), вы укажите интерпретатору, где именно вы намерены войти в режим отладки. Если у вас отсутствует новая версия Python (3.X), то придется внести дополнительную строку import pdb; pdb.set_trace().

Более подробную информацию о pdb вы найдете в соответствующей документации.

Real Python также предоставляет полезный обучающий материал о возможностях отладчика.

Заключение

Функция print() не заменит качественную отладку. Этот способ не приемлем для командной разработки, но вполне может подойти начинающим программистам. И почитателей print() гораздо больше, чем мы думаем. Во-первых, она ускоряет процесс отладки; во-вторых, вы узнаёте, каким должен быть ожидаемый результат; в-третьих, она моментально предоставляет наглядную информацию.

Не сдерживайте себя в стремлении изучить альтернативные варианты отладки. Возможно, вы найдете какой-то новый способ, который подойдет именно вам.

Если же вы намерены и дальше использовать print()  —  я только “за”. Главное, чтобы сеньоры были не против.

Читайте также:

Читайте нас в TelegramVK

Перевод статьи Martin Andersson Aaberge: Ignore the Professionals — Debug Your Python Code Using Print()