Ошибки в Python: как читать traceback и исправлять частые баги
Этот урок переведён с английского оригинала.Read in EnglishLeer en españolСообщить об ошибке в переводе
Увидев красное сообщение об ошибке, новичок первым делом паникует. Экран заполняется пугающим текстом, и кажется, что вы что-то серьёзно сломали. Но правда в том, что лучшего друга, чем сообщение об ошибке, у вас нет. Оно точно говорит, что пошло не так и где.
Профессиональные программисты видят ошибки каждый день. Эксперт отличается от новичка не тем, что не допускает ошибок, а тем, что умеет их читать. Как только вы научитесь читать сообщения об ошибках Python, отладка из пугающего занятия превратится в почти автоматическое.
В этом уроке вы научитесь читать трассировку (traceback) в Python, разберётесь в шести самых частых типах ошибок и соберёте в голове набор приёмов, которые помогают быстро исправлять баги.
Как читать трассировку (traceback) в Python
Когда Python натыкается на ошибку, он выводит трассировку: отчёт о том, что произошло. Большинство людей читают трассировку сверху вниз, а нужно наоборот. Всегда начинайте с последней строки.
Traceback (most recent call last): File "<exec>", line 5, in <module> File "<exec>", line 2, in greet TypeError: can only concatenate str (not "int") to str
Если запустить этот код, Python покажет трассировку. Вот как её читать, начиная снизу:
SyntaxError: Python не понимает ваш код
SyntaxError означает, что Python даже не может начать выполнять ваш код, потому что у него неправильная структура. Это похоже на грамматическую ошибку в обычной речи: предложение теряет смысл. Python находит такие ошибки ещё до того, как выполнит хотя бы одну строку.
SyntaxError: expected ':' (<string>, line 1) Common SyntaxError causes: 1. Missing colon after if/else/for/while/def 2. Mismatched parentheses or quotes 3. Using = instead of == in conditions 4. Incorrect indentation
Хорошая новость: SyntaxError обычно исправить проще всего. Python часто указывает прямо на проблему маленькой стрелкой (^) в том месте, где он запутался.
if temperature > 30
print('Hot!')if temperature > 30:
print('Hot!')NameError: Python не может найти имя
NameError означает, что вы использовали имя переменной или функции, которое Python не знает. Обычно причина в опечатке, в забытом определении переменной или в том, что переменную использовали до присваивания ей значения.
NameError: name 'usernme' is not defined NameError: name 'score' is not defined
total_price = 49.99
print(total_prce) # typo!total_price = 49.99
print(total_price)TypeError: неподходящий тип для операции
TypeError означает, что вы попытались сделать что-то с данными неподходящего типа. Например, сложить строку и число или вызвать то, что не является функцией. Python понимает, чего вы хотите, но типы не совпадают.
TypeError: can only concatenate str (not "int") to str TypeError: can't multiply sequence by non-int of type 'str' TypeError: add() takes 2 positional arguments but 3 were given
TypeError часто появляется при работе с вводом пользователя (он всегда приходит строкой) или когда функция неожиданно возвращает None.
age = 25
print('You are ' + age + ' years old')age = 25
print(f'You are {age} years old')IndexError и KeyError: обращение к тому, чего нет
IndexError возникает, когда вы обращаетесь к несуществующей позиции в списке. KeyError возникает, когда вы обращаетесь к несуществующему ключу словаря. В обоих случаях вы тянетесь к тому, чего там нет.
IndexError: list index out of range List length: 3 Valid indices: 0 to 2 KeyError: 'email'
В словарях KeyError можно избежать с помощью метода .get(): вместо ошибки он возвращает значение по умолчанию.
user = {'name': 'Alice'}
email = user['email'] # KeyError!user = {'name': 'Alice'}
email = user.get('email', 'Not provided')
print(email) # Not providedValueError: тип верный, значение нет
ValueError означает, что тип правильный, но само значение не подходит для операции. Классический пример: попытка превратить в целое число строку, в которой записано не число.
ValueError: invalid literal for int() with base 10: 'hello' ValueError: invalid literal for int() with base 10: '3.14' Converted: 3
ValueError часто встречается при обработке ввода пользователя. Пользователь может ввести «двадцать» вместо «20» или оставить поле пустым. Всегда проверяйте ввод перед преобразованием.
"abc" is not a valid number
Полезные советы по отладке
Вот краткая шпаргалка по отладке кода на Python. Эти приёмы работают для ошибок любого типа.
Вот краткая справка по ошибкам, которые будут встречаться вам чаще всего:
| Ошибка | Что означает | Как быстро исправить |
|---|---|---|
SyntaxError | Неправильная структура кода | Проверьте двоеточия, скобки, кавычки |
NameError | Переменная или функция не найдена | Проверьте написание, определяйте до использования |
TypeError | Неподходящий тип данных | Преобразуйте типы или проверьте аргументы функции |
IndexError | Индекс списка вне диапазона | Проверьте длину списка, помните, что индексы начинаются с 0 |
KeyError | Ключ словаря не найден | Используйте .get() или проверьте, что ключ есть |
ValueError | Тип верный, значение нет | Проверяйте данные перед преобразованием |
Упражнения
Пора потренировать навыки отладки! В большинстве упражнений вам дан неисправный код. Прочитайте сообщение об ошибке, найдите баг и исправьте его.
В этом коде есть SyntaxError. Найдите и исправьте ошибку, чтобы программа вывела:
Python is fun!
Let's learn more.В этом коде есть NameError. Найдите опечатку и исправьте её, чтобы программа вывела:
Hello, Alice! You have 3 new messages.В этом коде есть TypeError. Исправьте его, чтобы программа вывела:
Your total is $37.5Этот код пытается вывести последний цвет, но завершается с IndexError. Исправьте его, чтобы программа вывела:
Last color: greenЭтот код завершается с ошибкой, когда пытается преобразовать строку с ценой в целое число. Исправьте его, чтобы программа вывела:
Price in cents: 999Цена составляет "9.99" доллара, и мы хотим перевести её в центы (умножить на 100 и округлить до целого числа).
В этом коде ТРИ ошибки (по одной в каждом разделе, разделы отмечены комментариями Bug 1, Bug 2 и Bug 3). Исправьте их все, чтобы вывод был таким:
Student: Alice
Grade: 85
Passed: TrueИтоги: сообщения об ошибках в Python
Вот краткая справка по самым частым ошибкам в Python:
| Ошибка | Значение | Что проверить первым делом |
|---|---|---|
SyntaxError | Неправильная структура кода | Пропущенные двоеточия, скобки, кавычки |
NameError | Неизвестная переменная | Написание имени, порядок определения |
TypeError | Неподходящий тип | Проверьте типы с помощью type() |
IndexError | Неверный индекс списка | Длина списка, индексы с 0 |
KeyError | Неверный ключ словаря | Используйте .get() со значением по умолчанию |
ValueError | Неподходящее значение | Проверяйте перед преобразованием |
Золотые правила отладки:
print(type(x), x), чтобы проверить подозрительные переменныеЧто дальше?
Теперь, когда вы умеете читать сообщения об ошибках, можно уверенно браться за более сложные темы Python. Переходите к уроку [Списки в Python](/python/python-lists) и познакомьтесь с одной из самых мощных и универсальных структур данных в Python.