In Python 3.15,
there will be a fully immutable dictionary.
A new public immutable type, frozendict, is added to the builtins module.
It is expected that
frozendict will be "safe by design", because it prevents any unintended changes. This is useful not only for the CPython standard library, but also for third-party maintainers: you can rely on a reliable immutable dictionary type.
Why is this needed at all:
▪️Do you want to use a map as a key in another
dict or put it in a
set? A regular
dict is not allowed, but a
frozendict is (if the values are also hashable).
▪️
@functools.lru_cache() and arguments-dictionaries: it's difficult with a
dict, but normal with a
frozendict.
▪️Defaults in function arguments: instead of a "mutable default", you can give
frozendict(...) and not get surprises.
How it looks in the API:
▪️The constructor "like a dict":
frozendict(),
frozendict(**kwargs),
frozendict(mapping) or iterable pairs, plus you can mix with
**kwargs.
▪️The order of insertion is preserved (as in a regular
dict).
▪️The hash does not depend on the order of elements (logic via
frozenset(items)), and the comparison is also based on the content, not on the order.
▪️There is a union via
| and an "update"
|= (but
|= does not mutate the object, but creates a new one).
▪️
.copy() in CPython essentially returns the same object (shallow), and if you need deep copying, then
copy.deepcopy().
An important point:
frozendict is NOT inherited from
dict. This is done on purpose, so that you can't bypass the "immutability" by calling
dict.__setitem__ and similar tricks.
And a bonus for the stdlib: the authors have marked places where you can replace constant/public maps with
frozendict (including where
MappingProxyType is now used).
👉
@DataScience4