В модуль builtins добавляется новый публичный неизменяемый тип frozendict.
Ожидается, что
frozendict будет “safe by design”, потому что он предотвращает любые непреднамеренные изменения. Это полезно не только для стандартной библиотеки CPython, но и для сторонних мейнтейнеров: можно опираться на надежный неизменяемый тип словаря.Зачем это вообще нужно:
▪️Хочешь использовать мапу как ключ в другом
dict или засунуть в set? Обычный dict нельзя, а frozendict можно (если значения тоже хэшируемые). ▪️
@functools.lru_cache() и аргументы-словари: с dict будет сложно, с frozendict нормально. ▪️Дефолты в аргументах функций: вместо “мутабельного дефолта” можно давать
frozendict(...) и не ловить сюрпризы. Как выглядит по API:
▪️Конструктор “как у dict”:
frozendict(), frozendict(**kwargs), frozendict(mapping) или iterable пар, плюс можно смешивать с **kwargs. ▪️Порядок вставки сохраняется (как в обычном
dict). ▪️Хэш не зависит от порядка элементов (логика через
frozenset(items)), и сравнение тоже по содержимому, а не по порядку. ▪️Есть объединение через
| и “обновление” |= (но |= не мутирует объект, а создает новый). ▪️
.copy() в CPython по сути возвращает тот же объект (shallow), а если надо глубоко, то copy.deepcopy(). Важный момент:
frozendict НЕ наследуется от dict. Это специально, чтобы нельзя было обойти “неизменяемость” вызовом dict.__setitem__ и подобных трюков. И бонус для stdlib: авторы наметили места, где можно заменить константные/публичные мапы на
frozendict (в том числе там, где сейчас MappingProxyType). 👉 @PythonPortal