2103

How to create an immutable dictionary in python?

Question:

I want to subclass dict in python such that all the dictionaries of the sub-class are immutable.

I don't understand how does __hash__ affects the immutability, since in my understanding it just signifies the <strong>equality</strong> or <strong>non-equality</strong> of objects !

So, can __hash__ be used to implement immutability ? How ?

<strong>Update</strong>:

Objective is that common response from an API is available as a dict, which has to be shared as a global variable. So, that needs to be intact no matter what ?

Answer1:

I found an Official reference :

class imdict(dict): def __hash__(self): return id(self) def _immutable(self, *args, **kws): raise TypeError('object is immutable') __setitem__ = _immutable __delitem__ = _immutable clear = _immutable update = _immutable setdefault = _immutable pop = _immutable popitem = _immutable

Attribution : <a href="http://www.python.org/dev/peps/pep-0351/" rel="nofollow">http://www.python.org/dev/peps/pep-0351/</a>

Answer2:

<blockquote>

So, can __hash__ be used to implement immutability ?

</blockquote>

No, it can't. The object can be made mutable (or not) irrespective of what its __hash__ method does.

The relationship between immutable objects and __hash__ is that, since an immutable object cannot be changed, the value returned by __hash__ remains constant post-construction. For mutable objects, this may or may not be the case (the recommended practice is that such objects simply fail to hash).

For further discussion, see <a href="http://bugs.python.org/issue13707" rel="nofollow">Issue 13707: Clarify hash() constency period</a>.

Answer3:

Regarding the relationship between hashability and mutability:

To be useful, a hash implementation needs to fulfil the following properties:

<ol><li>

The hash value of two objects that compare equal using == must be equal.

</li> <li>

The hash value may not change over time.

</li> </ol>

These two properties imply that hashable classes cannot take mutable properties into account when comparing instances, and by contraposition that classes which do take mutable properties into account when comparing instances are not hashable. Immutable classes can be made hashable without any implications for comparison.

All of the built-in mutable types are not hashable, and all of the immutable built-in types are hashable. This is mainly a consequence of the above observations.

User-defined classes by default define comparison based on object identity, and use the id() as hash. They are mutable, but the mutable data is not taken into account when comparing instances, so they can be made hashable.

Making a class hashable does not make it immutable in some magic way. On the contrary, to make a dictionary hashable in a reasonable way while keeping the original comparison operator, you will first need to make it immutable.

<strong>Edit</strong>: Regarding your update:

There are several ways to provide the equivalent of global immutable dictionary:

<ol><li>

Use a collections.namedtuple() instance instead.

</li> <li>

Use a user-defined class with read-only properties.

</li> <li>

I'd usually go with something like this:

_my_global_dict = {"a": 42, "b": 7} def request_value(key): return _my_global_dict[key]

By the leading underscore, you make clear that _my_global_dict is an implementation detail not to be touched by application code. Note that this code would still allow to modify dictionary <em>values</em> if they happen to be mutable objects. You could solve this problem by returning copy.copy()s or copy.deepcopy()s of the values if necessary.

</li> </ol>

Recommend

  • Defining unicode variables in Python
  • Subclass in type hinting
  • Importing requests module does not work
  • opencv version 3.* HogDescriptor takes at most 1 argument (5 given)
  • OrderedDict not staying in order
  • Why doesn't the Python interpreter implicitly create the generator?
  • How do I translate LR(1) Parse into a Abstract syntax tree?
  • Debug.DrawLine not showing in the GameView
  • GridView breaks while scrolling
  • Installing iPhone App to iPhone
  • Jackson Parser: ignore deserializing for type mismatch
  • How to Cache Real-time Data?
  • How to use RequestBodyAdvice
  • Alert pop up with LWUIT
  • ImageMagick, replace semi-transparent white with opaque white
  • Q promise. Difference between .when and .then
  • does jqgrid support a multiple checkbox list for editing
  • Cannot connect to cassandra from Spark
  • Installing Hadoop, Java Exception about illegal characters at index 7?
  • Optimizing database types to compact database (SQLite)
  • How to make a tree having multiple type of nodes and each node can have multiple child nodes in java
  • Cross-Platform Protobuf Serialization
  • Incrementing object id automatically JS constructor (static method and variable)
  • Does CUDA 5 support STL or THRUST inside the device code?
  • When should I choose bucket sort over other sorting algorithms?
  • Hazelcast - OperationTimeoutException
  • To display the title for the current loaction in map in iphone
  • Alternatives to the OPTIONAL fallback SPARQL pattern?
  • Do I've to free mysql result after storing it?
  • Akka Routing: Reply's send to router ends up as dead letters
  • AT Commands to Send SMS not working in Windows 8.1
  • Arrays break string types in Julia
  • bootstrap to use multiple ng-app
  • How to get icons for entities from eclipse?
  • Rails 2: use form_for to build a form covering multiple objects of the same class
  • How can I get HTML syntax highlighting in my editor for CakePHP?
  • How do I configure my settings file to work with unit tests?
  • Turn off referential integrity in Derby? is it possible?
  • Is it possible to post an object from jquery to bottle.py?
  • JaxB to read class hierarchy