While frozendict
was rejected, a related class types.MappingProxyType
was added to public API in python 3.3.
I understand MappingProxyType
is just a wrapper around the underlying dict
, but despite that isn't it functionally equivalent to frozendict
?
In other words, what's the substantive difference between the original PEP 416 frozendict
and this:
from types import MappingProxyType def frozendict(*args, **kwargs): return MappingProxyType(dict(*args, **kwargs))
Of course MappingProxyType
is not hashable as is, but just as the PEP suggested for frozendict
, it can be made hashable after ensuring that all its values are hashable (MappingProxyType cannot be subclassed, so it would be require composition and forwarding of methods).
The MappingProxyType is just a simple proxy (i.e. interface) to access the real object (the real map, which on our example is dict). the suggested frozendict object is just as set is to frozenset. a read only (immutable) object which can only be changed upon creation.
I would just override the __setitem__() method of your dict. Note however, that this doesn't guarantee that the values of your dict will be immutable (say you have values that are lists, for example).
MappingProxyType
is a read only proxy for mapping (e.g. dict) objects.
frozendict
is an immutable dict
The proxy pattern is (quoting wikipedia):
A proxy, in its most general form, is a class functioning as an interface to something else.
The MappingProxyType
is just a simple proxy (i.e. interface) to access the real object (the real map, which on our example is dict).
the suggested frozendict
object is just as set is to frozenset. a read only (immutable) object which can only be changed upon creation.
So why do we need MappingProxyType
? example use case is where you want to pass a dictionary to another function but without it able to change your dictionary, it act as a read only proxy, (quoting python docs):
Read-only proxy of a mapping. It provides a dynamic view on the mapping’s entries, which means that when the mapping changes, the view reflects these changes.
lets see some example usage of the MappingProxyType
In [1]: from types import MappingProxyType In [2]: d = {'a': 1, 'b': 2} In [3]: m = MappingProxyType(d) In [4]: m['a'] Out[4]: 1 In [5]: m['a'] = 5 TypeError: 'mappingproxy' object does not support item assignment In [6]: d['a'] = 42 In [7]: m['a'] Out[7]: 42 In [8]: for i in m.items(): ...: print(i) ('a', 42) ('b', 2)
because the PEP did not make it into python, we cannot know for sure what the implementation that would be. by looking at the PEP we see that:
frozendict({'a': {'b': 1}})
would raise an exception as {'b': 1}
is not hashable value, but on your implementation it will create the object. of-course, you can add a validation for the value as noted on the PEP.
I assume part of the PEP was memory optimization and implementation of this kind of frozendict could have benefit from the performance of dict comparison using the __hash__
implementation.
MappingProxyType add immutability only on a first level:
>>> from types import MappingProxyType >>> d = {'a': {'b': 1}} >>> md = MappingProxyType(d) >>> md mappingproxy({'a': {'b': 1}}) >>> md['a']['b'] 1 >>> md['a']['b'] = 3 >>> md['a']['b'] 3
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With