Исключения Python KeyError и способы их обработки
Оглавление
- Что обычно означает ключевая ошибка Python
- Где еще вы могли бы увидеть ошибку ключа Python в стандартной библиотеке
- Когда вам нужно вызвать ошибку ключа Python в вашем собственном коде
- Как справиться с ошибкой ключа Python, когда вы ее видите
- Заключение
Смотрите сейчас, к этому уроку прилагается соответствующий видеокурс, созданный командой Real Python. Посмотрите его вместе с письменным руководством, чтобы углубить свое понимание: Исключения KeyError в Python и как с ними обращаться
Исключение Python KeyError - это распространенное исключение, с которым сталкиваются новички. Знание того, почему может возникнуть проблема KeyError, и некоторых решений, предотвращающих остановку вашей программы, являются важными шагами к совершенствованию в качестве программиста на Python.
К концу этого урока вы будете знать:
- Что обычно означает Python
KeyError - Где еще вы могли бы увидеть
KeyErrorв стандартной библиотеке - Как обращаться с
KeyError, когда вы видите это
Бесплатный бонус: Нажмите здесь, чтобы получить нашу бесплатную шпаргалку по Python, которая знакомит вас с основами Python 3, такими как работа с данными типы, словари, списки и функции Python.
Что обычно означает Python KeyError
Python KeyError исключение возникает при попытке получить доступ к ключу, которого нет в словаре (dict).
В официальной документации Python говорится, что KeyError вызывается при обращении к ключу сопоставления и не найден в сопоставлении. Отображение - это структура данных, которая преобразует один набор значений в другой. Наиболее распространенным отображением в Python является словарь.
Код Python KeyError является типом исключения LookupError и означает, что возникла проблема с получением ключа, который вы искали. Когда вы видите KeyError, это означает, что искомый ключ не найден.
В приведенном ниже примере вы можете увидеть словарь (ages), определенный с учетом возраста трех человек. Когда вы пытаетесь получить доступ к ключу, которого нет в словаре, возникает сообщение KeyError:
>>> ages = {'Jim': 30, 'Pam': 28, 'Kevin': 33} >>> ages['Michael'] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'Michael'предварительно> кодовый блок>Здесь попытка получить доступ к ключу
'Michael'в словареagesприводит к появлениюKeyError. В нижней части обратной связи вы получите соответствующую информацию:
- Тот факт, что был поднят вопрос о
KeyError - Ключ, который не удалось найти, который был
'Michael'
В предпоследней строке указано, какая строка вызвала исключение. Эта информация более полезна при выполнении кода на Python из файла.
Примечание: Когда в Python возникает исключение, это выполняется с помощью обратной трассировки. Обратная трассировка предоставляет вам всю необходимую информацию, позволяющую определить, почему возникло исключение и что его вызвало.
Научиться читать обратную трассировку Python и понимать, о чем она вам говорит, крайне важно для совершенствования в качестве программиста на Python. Чтобы узнать больше об обратной трассировке Python, ознакомьтесь с Разделом "Понимание обратной трассировки Python".
В приведенной ниже программе вы можете снова просмотреть словарь ages. На этот раз вам будет предложено ввести имя человека, чтобы получить возраст для:
1# ages.py 2 3ages = {'Jim': 30, 'Pam': 28, 'Kevin': 33} 4person = input('Get age for: ') 5print(f'{person} is {ages[person]} years old.')предварительно> кодовый блок>Этот код будет использовать имя, которое вы укажете в приглашении, и попытается получить возраст этого человека. Все, что вы введете в командной строке, будет использовано в качестве ключа к словарю
agesв строке 4.Повторяя неудачный пример из приведенного выше, мы получаем еще одну обратную трассировку , на этот раз с информацией о строке в файле, из которой вызван
KeyError:$ python ages.py Get age for: Michael Traceback (most recent call last): File "ages.py", line 4, in <module> print(f'{person} is {ages[person]} years old.') KeyError: 'Michael'предварительно> кодовый блок>Программа завершает работу с ошибкой, если вы вводите ключ, которого нет в словаре. Здесь последние несколько строк обратной трассировки указывают на проблему.
File "ages.py", line 4, in <module>указывает, в какой строке какого файла возникло результирующее исключениеKeyError. Затем вам будет показана эта строка. Наконец, исключениеKeyErrorсодержит недостающий ключ.Итак, вы можете видеть, что последняя строка обратной связи
KeyErrorсама по себе не дает вам достаточно информации, но строки перед ней могут значительно приблизить вас к пониманию того, что пошло не так.Примечание: Как и в примере выше, в большинстве других примеров в этом руководстве используются f-строки, которые были представлены в Python 3.6.
Где еще Вы могли бы увидеть Python
KeyErrorв стандартной библиотекеВ подавляющем большинстве случаев Python
KeyErrorвызывается, потому что ключ не найден в словаре или подклассе словаря (например,os.environ).В редких случаях вы также можете увидеть, что он вызывается в других местах стандартной библиотеки Python, например, в модуле
zipfile, если элемент не найден в ZIP-архиве. Однако эти места сохраняют то же семантическое значение, что и PythonKeyError, который не находит запрошенный ключ.В следующем примере вы можете увидеть использование класса
zipfile.ZipFileдля извлечения информации о ZIP-архиве с помощью.getinfo():>>> from zipfile import ZipFile >>> zip_file = ZipFile('the_zip_file.zip') >>> zip_file.getinfo('something') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/path/to/python/installation/zipfile.py", line 1304, in getinfo 'There is no item named %r in the archive' % name) KeyError: "There is no item named 'something' in the archive"предварительно> кодовый блок>На самом деле это не похоже на поиск по ключу в словаре. Вместо этого это вызов
zipfile.ZipFile.getinfo(), который вызывает исключение.Обратная трассировка также выглядит немного по-другому, поскольку в ней содержится немного больше информации, чем просто отсутствующий ключ:
KeyError: "There is no item named 'something' in the archive".И последнее, на что следует обратить внимание, это то, что строки, из-за которой возникло значение
KeyError, в вашем коде нет. Это указано в кодеzipfile, но предыдущие строки обратной трассировки указывают, какие строки в вашем коде вызвали проблему.Когда Вам нужно создать Python
KeyErrorв вашем собственном кодеМогут быть случаи, когда для имеет смысл вызвать исключение Python
KeyErrorв вашем собственном коде. Это можно сделать, используя ключевое словоraiseи вызвав исключениеKeyError:raise KeyError(message)предварительно> кодовый блок>Обычно
messageявляется отсутствующим ключом. Однако, как и в случае с пакетомzipfile, вы могли бы предоставить немного больше информации, чтобы помочь следующему разработчику лучше понять, что пошло не так.Примечание: Если вы хотите более подробно ознакомиться с использованием
raise, ознакомьтесь с Python'sraise: Эффективное создание исключений в вашем коде.Если вы решите использовать Python
KeyErrorв своем собственном коде, просто убедитесь, что ваш вариант использования соответствует семантическому значению, стоящему за исключением. Это должно означать, что искомый ключ не найден.Как обращаться с Python
KeyErrorКогда Вы его видитеКогда вы сталкиваетесь с
KeyError, есть несколько стандартных способов справиться с этим. В зависимости от вашего варианта использования, некоторые из этих решений могут быть лучше других. Конечная цель состоит в том, чтобы предотвратить возникновение неожиданныхKeyErrorисключений.Обычное решение:
.get()Если
KeyErrorвызывается в результате неудачного поиска ключа по словарю в вашем собственном коде, вы можете использовать.get(), чтобы вернуть либо значение, найденное по указанному ключу, либо значение по умолчанию.Как и в предыдущем примере с поиском возраста, в следующем примере показан лучший способ получить возраст из словаря, используя ключ, указанный в командной строке:
1# ages.py 2 3ages = {'Jim': 30, 'Pam': 28, 'Kevin': 33} 4person = input('Get age for: ') 5age = ages.get(person) 6 7if age: 8 print(f'{person} is {age} years old.') 9else: 10 print(f"{person}'s age is unknown.")предварительно> кодовый блок>Здесь, в строке 5, показано, как вы можете получить значение возраста из
ages, используя.get(). В результатеageпеременная будет иметь значение возраста, найденное в словаре для предоставленного ключа, или значение по умолчанию,None<<в данном случае .На этот раз вы не получите исключение
KeyError, вызванное использованием более безопасного метода.get()для получения возраста вместо того, чтобы пытаться получить доступ к ключу напрямую:$ python ages.py Get age for: Michael Michael's age is unknown.предварительно> кодовый блок>В приведенном выше примере выполнения
KeyErrorбольше не вызывается при вводе неверного ключа. Ключ'Michael'не найден в словаре, но, используя.get(), мы получаем возвращенныйNone, а не поднятыйKeyError.Переменная
ageбудет содержать либо возраст человека, указанный в словаре, либо значение по умолчанию (Noneпо умолчанию). Вы также можете указать другое значение по умолчанию в вызове.get(), передав второй аргумент.Это строка 5 из приведенного выше примера с другим возрастом по умолчанию, указанным с помощью
.get():age = ages.get(person, 0)предварительно> кодовый блок>Здесь вместо
'Michael', возвращающегоNone, будет возвращено0, потому что ключ не найден, а возвращаемое значение по умолчанию теперь0.Редкое решение: Проверка наличия ключей
Иногда возникает необходимость определить наличие ключа в словаре. В таких случаях использование
.get()может не дать вам правильной информации. ПолучениеNone, возвращенного из вызова.get(), может означать, что ключ не был найден или что значение, найденное в ключе в словаре, на самом деле являетсяNone.Для словаря или объекта, подобного словарю, вы можете использовать оператор
in, чтобы определить, присутствует ли ключ в отображении. Этот оператор вернет логическое значение (TrueилиFalse, указывающее, найден ли ключ в словаре.В этом примере вы получаете
responseсловарь из вызова API. Этот ответ может содержать ключевое значениеerror, определенное в ответе, которое указывает на то, что ответ находится в состоянии ошибки:1# parse_api_response.py 2... 3# Assuming you got a `response` from calling an API that might 4# have an error key in the `response` if something went wrong 5 6if 'error' in response: 7 ... # Parse the error state 8else: 9 ... # Parse the success stateпредварительно> кодовый блок>Здесь есть разница в проверке наличия ключа
errorвresponseи получении значения по умолчанию из ключа. Это редкий случай, когда на самом деле вас интересует, есть ли ключ в словаре, а не значение этого ключа.Общее решение:
tryexceptКак и в случае с любым исключением, вы всегда можете использовать блок
tryexcept, чтобы изолировать потенциальный код, вызывающий исключение, и предоставить решение для резервного копирования.Вы можете использовать блок
tryexceptв аналогичном примере, как и раньше, но на этот раз он содержит сообщение по умолчанию, которое будет напечатано, если в обычном случае будет выведено значениеKeyError:1# ages.py 2 3ages = {'Jim': 30, 'Pam': 28, 'Kevin': 33} 4person = input('Get age for: ') 5 6try: 7 print(f'{person} is {ages[person]} years old.') 8except KeyError: 9 print(f"{person}'s age is unknown.")предварительно> кодовый блок>Здесь вы можете увидеть обычный регистр в блоке
tryдля ввода имени и возраста пользователя. Резервный вариант находится в блокеexcept, где, если в обычном случае отображаетсяKeyError, то резервный вариант должен выводить другое сообщение.
tryexceptБлочное решение также является отличным решением для других приложений, которые могут не поддерживать.get()или операторin. Это также лучшее решение, еслиKeyErrorвызывается из кода другого пользователя.Вот пример повторного использования пакета
zipfile. На этот раз блокtryexceptдает нам возможность предотвратить остановку программы из-за исключенияKeyError:>>> from zipfile import ZipFile >>> zip = ZipFile('the_zip_file.zip') >>> try: ... zip.getinfo('something') ... except KeyError: ... print('Can not find "something"') ... Can not find "something"предварительно> кодовый блок>Поскольку класс
ZipFileне предоставляет.get(), как это делает словарь, вам нужно использовать решениеtryexcept. В этом примере вам не нужно заранее знать, какие значения допустимы для передачи.getinfo().Заключение
Теперь вы знаете несколько распространенных случаев, когда может возникать исключение Python
KeyError, и несколько отличных решений, которые вы могли бы использовать, чтобы предотвратить остановку вашей программы.Теперь, когда в следующий раз вы увидите сообщение
KeyError, вы будете знать, что это, вероятно, просто неправильный поиск по ключу в словаре. Вы также сможете найти всю необходимую информацию, чтобы определить, откуда взялась ошибка, просмотрев последние несколько строк обратной трассировки.Если проблема заключается в поиске ключа по словарю в вашем собственном коде, то вы можете переключиться с доступа к ключу непосредственно в словаре на использование более безопасного метода
.get()с возвращаемым значением по умолчанию. Если проблема не связана с вашим собственным кодом, то лучше всего использовать блокtryexceptдля управления потоком кода.Исключения не обязательно должны быть пугающими. Как только вы научитесь понимать информацию, предоставляемую вам в их трассировках, и основную причину исключения, вы сможете использовать эти решения, чтобы сделать работу ваших программ более предсказуемой.
<статус завершения article-slug="python-keyerror" class="btn-group mb-0" data-api-article-bookmark-url="/api/v1/articles/python-keyerror/bookmark/" статус завершения data-api-article-url="/api/v1/articles/ошибка python-ключа/completion_status/"> статус завершения> <кнопка поделиться bluesky-text="Интересная статья на #Python от @realpython.com :" email-body="Ознакомьтесь с этой статьей на Python:%0A%0APython KeyError Исключения и как с ними справляться" email-subject="Статья на Python для вас" twitter-text="Интересная статья на #Python от @realpython:" url="https://realpython.com/python-keyerror /" url-title="Исключения Python KeyError и как с ними обращаться"> кнопка поделиться>Смотрите сейчас, к этому уроку прилагается соответствующий видеокурс, созданный командой Real Python. Посмотрите его вместе с письменным руководством, чтобы углубить свое понимание: Исключения KeyError в Python и как с ними обращаться
Back to Top