Выходим за рамки традиционного метода и защищаем свой код
Словарь — это несортированный набор ключей и значений. Это значит, что:
- Каждый элемент словаря состоит из термина (ключ) и его определения (значение).
- Ключи должны быть уникальными для данного словаря — никаких повторений.
- Ключи в словаре не имеют такого явного порядка расположения, который есть у элементов списка.
Чтобы создать словарь, используйте фигурные скобки, внутри которых запишите пары ключ: значение через запятую. Вот так:
author = {
"first_name": "Robinson",
"last_name": "Crusoe",
"username": "Friday1719"
}
Традиционный (и небезопасный) способ получения значения из словаря.
При обычном доступе к значению элемента из словаря используются квадратные скобки. При использовании такой записи после имени словаря в квадратных скобках указывается ключ:
author = {
"first_name": "Robinson",
"last_name": "Crusoe",
"username": "Friday1719"
}
print(author['username']) # выведет Friday1719
print(author['middle_initial']) # получим ошибку KeyError: 'middle_initial'
Обратите внимание, что попытка обратиться к значению по ключу, которого нет в словаре, вызовет исключение KeyError. Это может создать серьёзные проблемы, особенно при работе с непредсказуемыми рабочими данными.
Конечно, можно воспользоваться конструкцией try/except или использовать инструкцию if. Но такое повышенное внимание к столь простой операции лишь загромождает код.
author = {}
try:
print(author['username'])
except KeyError as e:
print(e) # 'username'
if 'username' in author:
print(author['username'])
Если у вас за плечами опыт разработки на JavaScript, то вам, возможно, захочется получить значение из словаря с помощью точечной нотации. Но в Python'е это не сработает.
author = {
"first_name": "Robinson",
"last_name": "Crusoe",
"username": "Friday1719"
}
print(author.username)
# AttributeError: 'dict' object has no attribute 'username'
Используем метод get()
Когда вам нужно получить значение из словаря, то самым безопасным способом будет использование метода get(). У этого метода есть два параметра:
- Первый (обязателен): имя ключа, по которому мы хотим получить значение. Это имя может быть строкой или может быть именем переменной, если наш ключ может меняться по ходу программы.
- Второй (не обязателен): значение, которое будет использовано, если нашего ключа в словаре вдруг не окажется.
author = {
"first_name": "Robinson",
"last_name": "Crusoe",
"username": "Friday1719"
}
print(author.get('username')) # выведет Friday1719
print(author.get('middle_initial', “Monday1917”)) # выведет Monday1917
Если ключ существует в словаре, то метод get() работает точно таким же образом, как и обращение по ключу в квадратных скобках. Зато в случае, когда такого ключа в словаре нет, метод get() вернёт значение по умолчанию, избавив вас от необходимости обрабатывать исключение.
Значением по умолчанию может быть любой допустимый в данном контексте объект. Не забывайте о том, что этот параметр не обязателен. Поэтому, если вы его не укажете явным образом, то при попытке обратиться по несуществующему в словаре ключу, метод get() вернёт объект None.
Используем метод setdefault()
Иногда вам будет нужно не только безопасно получить данные из словаря, но и также безопасно добавить новые данные в словарь. Для этого у словарей есть метод setdefault(). Он имеет те же параметры, что и метод get(), но в отличие от последнего, при обращении к словарю по несуществующему ключу, он не только вернёт переданное по умолчанию значение, но и создаст в словаре новый элемент с этим ключом и переданным значением. Если при обращении к словарю с помощью метода setdefault() передаваемый ключ уже есть в словаре, то данный метод оставит словарь без изменений.
author = {
"first_name": "Robinson",
"last_name": "Crusoe",
"username": "Friday1719"
}
print(author.setdefault('username')) # выведет Friday1719
print(author.setdefault('middle_initial', “Monday”)) # выведет Monday и создаст
# в словаре элемент с ключом 'middle_initial' и значением для этого ключа “Monday”
В примере выше мы видим, что поведение метода setdefault() ничем не отличается от поведения метода get() или от применения квадратных скобок при обращении к словарю по существующему в нём ключу. В случае, если такого ключа в словаре нет, то метод setdefault() не только вернёт в программу значение своего второго аргумента (как и метод get()), но и создаст в словаре элемент с переданными ему ключом и значением. Это поведение метода setdefault() и отличает его от метода get().
Теперь, если выполнить пример выше и вывести элементы словаря, то мы получим такой результат:
print(author)
{
"first_name": "Robinson",
"last_name": "Crusoe",
"username": "Friday1719"
"middle_initial": "Monday"
}
Применение методов get() и setdefault() является первоклассной техникой при обращении к значениям словаря. Нужно лишь время, чтобы отказаться от старых привычек и начать использовать эту технику на практике.
Если вам нужно только получить значение из словаря, то ваш помощник — метод get().
Если же вам нужно безопасно добавить новое значение в словарь, то вызывайте метод setdefault().
tumbler
И ни единого слова о датаклассах...
TyVik
Вот тоже в первую очередь о них подумал. По моей практике в 90% случаев словари можно заменить ими, и получится более сопровождаемый код. В частности, все возможные «ключи» сразу видны.
PyVolshebnyi
На самом деле с датаклассами огрооомные проблемы, что с наследованием, что с представлением их как обычных словарей. Я некоторое время был влюблен в
typing.TypedDict
, но и у них проблемы с тем, чтоupdate
требует кастов. В итоге, пришлось велосипедить свой класс, который очень похож наdataclass
, но на самом делеUserDict
В общем, счейчас в питоне нет правильного решения для типизированных словарей.
tumbler
Дык для наследования можно и обычные классы написать, раз с дженериками проблема?