Python
Метод dict.get в Python: значения по умолчанию и частые ошибки
dict.get() нужен, когда значение в словаре может отсутствовать, а программа не должна падать с KeyError. Метод возвращает значение по ключу, если ключ есть, и запасное значение, если ключа нет
Самая частая практическая ситуация — данные пришли из формы, файла, API или парсера: часть полей заполнена, часть пропущена. Через квадратные скобки удобно читать обязательные поля, а через get() — необязательные
По этой теме полезно отдельно посмотреть Составьте еженедельное расписание занятий, чтобы расширить контекст и сравнить подходы
По этой теме полезно отдельно посмотреть Аннотации типов для декораторов в Python, чтобы расширить контекст и сравнить подходы
Чем get отличается от квадратных скобок
Квадратные скобки требуют, чтобы ключ существовал. Если ключа нет, будет ошибка
user = {"name": "Анна"}
print(user["name"])
print(user["city"])
get() ведет себя мягче. Если ключа нет, он вернет None или значение, которое вы передали вторым аргументом
user = {"name": "Анна"}
name = user.get("name")
city = user.get("city", "город не указан")
print(name)
print(city)
Используйте квадратные скобки для обязательных данных, отсутствие которых должно быть ошибкой. Используйте get() для необязательных полей, где запасной вариант нормален
Значение по умолчанию
Второй аргумент get() помогает сразу задать понятный запасной текст, число, список или словарь
settings = {"theme": "dark"}
theme = settings.get("theme", "light")
language = settings.get("language", "ru")
limit = settings.get("limit", 10)
print(theme, language, limit)
Не выбирайте default случайно. Если поле числовое, запасное значение тоже должно быть числом. Если дальше код ожидает список, default лучше сделать списком. Иначе ошибка просто переедет на следующую строку
None и пустое значение
Важная ловушка: get() использует default только тогда, когда ключа нет. Если ключ есть, но значение равно None, пустой строке или нулю, метод вернет именно это значение
user = {"city": None, "age": 0, "name": ""}
print(user.get("city", "город не указан"))
print(user.get("age", 18))
print(user.get("name", "без имени"))
Если вам нужно заменить еще и пустые значения, используйте дополнительную проверку
user = {"name": ""}
name = user.get("name")
if not name:
name = "без имени"
print(name)
Такой подход полезен для вывода на страницу, отчета или сообщения пользователю
get для подсчета частот
Метод часто используют для счетчиков. Если слово встречается впервые, берем ноль и прибавляем единицу
words = ["python", "sql", "python", "html", "python"]
counts = {}
for word in words:
counts[word] = counts.get(word, 0) + 1
print(counts)
Здесь counts.get(word, 0) означает: если слова еще нет в словаре, считай, что оно встретилось ноль раз
Вложенные словари
Для вложенных данных get() помогает аккуратно пройти несколько уровней, но длинные цепочки лучше не делать слишком умными
profile = {
"user": {
"name": "Анна",
"contacts": {"telegram": "@anna"}
}
}
user = profile.get("user", {})
contacts = user.get("contacts", {})
telegram = contacts.get("telegram", "не указан")
print(telegram)
Если структура сложная, разбивайте чтение на несколько строк. Так легче увидеть, на каком уровне пропало значение
Частые ошибки
Скрывать обязательную ошибку
Если поле обязательно, не надо везде ставить get(). Иногда лучше получить KeyError и сразу увидеть, что данные пришли неправильные
Использовать неподходящий default
items = data.get("items", "") выглядит безопасно, но если дальше нужен цикл по списку, лучше использовать [], а не строку
Путать отсутствие ключа и пустое значение
Ключ может существовать, но хранить None, 0, False или пустую строку. Это разные ситуации, и код должен учитывать смысл данных
Практика
Сделайте словарь product с полями title, price, discount. Прочитайте название через квадратные скобки, скидку через get(), а описание через get("description", "описания нет")
Затем поменяйте данные: удалите discount, поставьте description равным пустой строке, добавьте price = 0. Посмотрите, где нужен default, а где нужна отдельная проверка
Часто задаваемые вопросы
Можно ли всегда использовать get вместо квадратных скобок?
Не стоит. Для обязательных полей квадратные скобки честнее: если данных нет, ошибка покажет проблему сразу
Почему get вернул None, хотя указан default?
Потому что ключ есть в словаре, а его значение равно None. Default используется только при отсутствии ключа
Чем заменить get для счетчиков?
Можно использовать collections.Counter или defaultdict, но get() полезен как простой первый вариант
Таблица выбора: get, скобки или setdefault
| Ситуация | Что использовать | Почему |
|---|---|---|
| ключ обязателен | data["id"] |
отсутствие должно быть заметной ошибкой |
| поле необязательное | data.get("comment", "") |
можно подставить спокойное значение |
| нужно добавить значение при отсутствии | setdefault или явное присваивание |
get словарь не меняет |
None тоже нужно заменить |
value = data.get("x") or fallback |
второй аргумент не заменяет найденный None |
Практика с настройками
def normalize_config(config):
host = config["host"]
port = config.get("port", 5432)
debug = config.get("debug", False)
return {"host": host, "port": port, "debug": debug}
print(normalize_config({"host": "localhost"}))
В этом примере host обязателен, а port и debug имеют безопасные значения по умолчанию. Именно такое разделение делает get полезным, а не случайным