frozendict

About

frozendict is an immutable wrapper around dictionaries that implements the complete mapping interface. It can be used as a drop-in replacement for dictionaries where immutability is desired.

Of course this is Python, and you can still poke around the object’s internals if you want.

The frozendict constructor mimics dict, and all of the expected interfaces (iter, len, repr, hash, getitem) are provided. Note that a frozendict does not guarantee the immutability of its values, so the utility of the hash method is restricted by usage.

The only difference is that the copy() method of frozendict takes variable keyword arguments, which will be present as key/value pairs in the new, immutable copy.

Usage

>>> from cawdrey import frozendict
>>>
>>> fd = frozendict({ 'hello': 'World' })
>>>
>>> print fd
<frozendict {'hello': 'World'}>
>>>
>>> print fd['hello']
'World'
>>>
>>> print fd.copy(another='key/value')
<frozendict {'hello': 'World', 'another': 'key/value'}>
>>>

In addition, frozendict supports the + and - operands. If you add a dict-like object, a new frozendict will be returned, equal to the old frozendict updated with the other object. Example:

>>> frozendict({"Sulla": "Marco", 2: 3}) + {"Sulla": "Marò", 4: 7}
<frozendict {'Sulla': 'Marò', 2: 3, 4: 7}>
>>>

You can also subtract an iterable from a frozendict. A new frozendict will be returned, without the keys that are in the iterable. Examples:

>>> frozendict({"Sulla": "Marco", 2: 3}) - {"Sulla": "Marò", 4: 7}
<frozendict {'Sulla': 'Marco', 2: 3}>
>>> frozendict({"Sulla": "Marco", 2: 3}) - [2, 4]
<frozendict {'Sulla': 'Marco'}>
>>>

Some other examples:

>>> from cawdrey import frozendict
>>> fd = frozendict({"Sulla": "Marco", "Hicks": "Bill"})
>>> print(fd)
<frozendict {'Sulla': 'Marco', 'Hicks': 'Bill'}>
>>> print(fd["Sulla"])
Marco
>>> fd["Bim"]
KeyError: 'Bim'
>>> len(fd)
2
>>> "Sulla" in fd
True
>>> "Sulla" not in fd
False
>>> "Bim" in fd
False
>>> hash(fd)
835910019049608535
>>> fd_unhashable = frozendict({1: []})
>>> hash(fd_unhashable)
TypeError: unhashable type: 'list'
>>> fd2 = frozendict({"Hicks": "Bill", "Sulla": "Marco"})
>>> print(fd2)
<frozendict {'Hicks': 'Bill', 'Sulla': 'Marco'}>
>>> fd2 is fd
False
>>> fd2 == fd
True
>>> frozendict()
<frozendict {}>
>>> frozendict(Sulla="Marco", Hicks="Bill")
<frozendict {'Sulla': 'Marco', 'Hicks': 'Bill'}>
>>> frozendict((("Sulla", "Marco"), ("Hicks", "Bill")))
<frozendict {'Sulla': 'Marco', 'Hicks': 'Bill'}>
>>> fd.get("Sulla")
'Marco'
>>> print(fd.get("God"))
None
>>> tuple(fd.keys())
('Sulla', 'Hicks')
>>> tuple(fd.values())
('Marco', 'Bill')
>>> tuple(fd.items())
(('Sulla', 'Marco'), ('Hicks', 'Bill'))
>>> iter(fd)
<dict_keyiterator object at 0x7feb75c49188>
>>> frozendict.fromkeys(["Marco", "Giulia"], "Sulla")
<frozendict {'Marco': 'Sulla', 'Giulia': 'Sulla'}>
>>> fd["Sulla"] = "Silla"
TypeError: 'frozendict' object does not support item assignment
>>> del fd["Sulla"]
TypeError: 'frozendict' object does not support item deletion
>>> fd.clear()
AttributeError: 'frozendict' object has no attribute 'clear'
>>> fd.pop("Sulla")
AttributeError: 'frozendict' object has no attribute 'pop'
>>> fd.popitem()
AttributeError: 'frozendict' object has no attribute 'popitem'
>>> fd.setdefault("Sulla")
AttributeError: 'frozendict' object has no attribute 'setdefault'
>>> fd.update({"Bim": "James May"})
AttributeError: 'frozendict' object has no attribute 'update'

API Reference

class frozendict(*args, **kwargs)[source]

Bases: FrozenBase[~KT, ~VT]

An immutable wrapper around dictionaries that implements the complete collections.abc.Mapping interface. It can be used as a drop-in replacement for dictionaries where immutability is desired.

Methods:

__add__(other, *args, **kwargs)

If you add a dict-like object, a new frozendict will be returned, equal to the old frozendict updated with the other object.

__and__(other, *args, **kwargs)

Returns a new frozendict, that is the intersection between self and other.

__sub__(other, *args, **kwargs)

The method will create a new frozendict, result of the subtraction by other.

copy(*args, **kwargs)

Return a copy of the dictionary.

sorted(*args[, by])

Return a new frozendict, with the element insertion sorted.

__add__(other, *args, **kwargs)[source]

If you add a dict-like object, a new frozendict will be returned, equal to the old frozendict updated with the other object.

__and__(other, *args, **kwargs)[source]

Returns a new frozendict, that is the intersection between self and other.

If other is a dict-like object, the intersection will contain only the items in common.

If other is another iterable, the intersection will contain the items of self which keys are in other.

Iterables of pairs are not managed differently. This is for consistency.

Beware! The final order is dictated by the order of other. This allows the coder to change the order of the original frozendict.

The last two behaviours breaks voluntarily the dict.items() API, for consistency and practical reasons.

__sub__(other, *args, **kwargs)[source]

The method will create a new frozendict, result of the subtraction by other.

If other is a dict-like, the result will have the items of the frozendict that are not in common with other.

If other is another type of iterable, the result will have the items of frozendict without the keys that are in other.

copy(*args, **kwargs)[source]

Return a copy of the dictionary.

Return type

~_D

sorted(*args, by='keys', **kwargs)[source]

Return a new frozendict, with the element insertion sorted. The signature is the same as the builtin sorted function, except for the additional parameter by, that is 'keys' by default and can also be 'values' and 'items'. So the resulting frozendict can be sorted by keys, values or items.

If you want more complicated sorts read the documentation of sorted.

The the parameters passed to the key function are the keys of the frozendict if by = "keys", and are the items otherwise.

Note

Sorting by keys and items achieves the same effect. The only difference is when you want to customize the sorting passing a custom key function. You could achieve the same result using by = "values", since also sorting by values passes the items to the key function. But this is an implementation detail and you should not rely on it.