Источник: Nuances of Programming
Если вы скажете профессиональным программистам, что используете print() для отслеживания ошибок, готовьтесь уворачиваться от летящих в вашу сторону стульев. Есть ли смысл продираться через дебри трассировки стека с полной настройкой отладки, будучи новичком? Некоторые скажут “да”, поскольку они изначально научились это делать. Я же утверждаю: “Любые средства хороши — был бы результат”.
Это совсем не значит, что вам не нужно учиться распознавать ошибки — речь о другом. Когда вы программируете в свое удовольствие или намереваетесь создать для кого-либо небольшие фрагменты кода, так ли необходимо проводить отладку на профессиональном уровне? Если вы занимаетесь программированием себе на радость и в свободное время, то вряд ли вам потребуется проводить “образцовую” отладку на протяжении всей вашей карьеры разработчика.
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 (визуализация выполнения).
После этого вы сможете работать с кодом, переходя от одной строки к другой. Код находится с левой стороны, а вывод данных — справа.
В следующем примере показан заключительный этап программы (шаг 9). В строке 4 происходит выполнение sum_input(10,10), и справа мы видим функцию и значение, которое она возвращает.
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
С помощью 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, то среагирует Помощник:
Помощник также снабжает нас подсказками, облегчая процесс поиска и устранения ошибок. Если мы развернем вопрос “Did you misspell it (somewhere)?”, в котором он интересуется, а правильно ли было написано имя, то Thonny покажет нам похожие варианты имен и станет очевидно, где была допущена ошибка.
Если вы запускаете режим отладки, то Thonny пошагово выполнит код и покажет все, что в нем происходит:
Он останавливается на строке 24 с инструкцией if.
pdb — встроенный отладчик Python
Если же вы предпочитаете работать в терминале, то Python оснащен встроенным отладчиком, известным как pdb. Благодаря ему вам не приходится повсюду в коде применять функции print(). Помимо этого, вы можете проверять функции и переменные и тестировать код в реальном режиме без редактирования его исходного варианта. Используя данный способ отладки, вы не ломаете код только из-за необходимости протестировать те или иные случаи.
Просто добавив в код breakpoint(), вы укажите интерпретатору, где именно вы намерены войти в режим отладки. Если у вас отсутствует новая версия Python (3.X), то придется внести дополнительную строку import pdb; pdb.set_trace().
Более подробную информацию о pdb вы найдете в соответствующей документации.
Real Python также предоставляет полезный обучающий материал о возможностях отладчика.
Заключение
Функция print() не заменит качественную отладку. Этот способ не приемлем для командной разработки, но вполне может подойти начинающим программистам. И почитателей print() гораздо больше, чем мы думаем. Во-первых, она ускоряет процесс отладки; во-вторых, вы узнаёте, каким должен быть ожидаемый результат; в-третьих, она моментально предоставляет наглядную информацию.
Не сдерживайте себя в стремлении изучить альтернативные варианты отладки. Возможно, вы найдете какой-то новый способ, который подойдет именно вам.
Если же вы намерены и дальше использовать print() — я только “за”. Главное, чтобы сеньоры были не против.
Читайте также:
Перевод статьи Martin Andersson Aaberge: Ignore the Professionals — Debug Your Python Code Using Print()