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.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.

__contains__(key)

Return key in self.

__eq__(other)

Return self == other.

__getitem__(key)

Return self[key].

__iter__()

Iterates over the dictionary’s keys.

__len__()

Returns the number of keys in the dictionary.

__repr__()

Return a string representation of the DictWrapper.

__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.

fromkeys(iterable[, value])

Create a new dictionary with keys from iterable and values set to value.

get(k[, default])

Return the value for k if k is in the dictionary, else default.

items()

Returns a set-like object providing a view on the bdict's items.

keys()

Returns a set-like object providing a view on the bdict's keys.

sorted(*args[, by])

Return a new frozendict, with the element insertion sorted.

values()

Returns an object providing a view on the bdict's values.

__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.

__contains__(key)

Return key in self.

Parameters

key (object)

Return type

bool

__eq__(other)

Return self == other.

Return type

bool

__getitem__(key)

Return self[key].

Parameters

key (~KT)

Return type

~VT

__iter__()

Iterates over the dictionary’s keys.

Return type

Iterator[~KT]

__len__()

Returns the number of keys in the dictionary.

Return type

int

__repr__()

Return a string representation of the DictWrapper.

Return type

str

__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

classmethod fromkeys(iterable, value=None)

Create a new dictionary with keys from iterable and values set to value.

Return type

FrozenBase[~KT, ~VT]

get(k, default=None)

Return the value for k if k is in the dictionary, else default.

Parameters
  • k – The key to return the value for.

  • default – The value to return if key is not in the dictionary. Default None.

items()

Returns a set-like object providing a view on the bdict's items.

Return type

AbstractSet[Tuple[~KT, ~VT]]

keys()

Returns a set-like object providing a view on the bdict's keys.

Return type

AbstractSet[~KT]

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.

values()

Returns an object providing a view on the bdict's values.

Return type

ValuesView[~VT]