24. freeze — Freeze: create frozen objects

This module contains tools to create immutable objects, objects that can not be changed. Python contains the following immutable ojects: bool, int, float, str, tuple. The tuple is not completely immutable: you can not add or remove items to it, but it may contain items that can be changed. Then a read access to the item is enough to allow changes to that item. This is a general observation for all container types: to make the container contents immutable, the container class itself must be frozen, but also all of the items contained in it.

This module provides two immutable container classes: FrozenList and FrozenDict. But it also provides methods to create your own frozen classes and helps to freeze and thaw objects. Note that frozen objects are not completely unchangeable: that is just impossible. But the data are protected against inadvertent changes by the user. They must explicitely be thawed to change them with normal methods. Besides the FrozenList and FrozenDict classes, this module provides the following functions:

  • freeze(): make an object immutable

  • thaw(): make a frozen objects mutable again

  • frozen(): check if an object is immutable

Examples

Create a frozen list and try to change it:

>>> FL = FrozenList([True, 1, 'abc'])
>>> FL[1] = 2
Traceback (most recent call last):
...
TypeError: 'FrozenList' object does not support item assignment

Same for a frozen dict:

>>> FD = FrozenDict({'a':1, 'b':'qwe'})
>>> del FD['a']
Traceback (most recent call last):
...
TypeError: 'FrozenDict' object does not support item deletion

freeze() and thaw() recursively freeze or thaw all items in the containers:

>>> F = freeze([True, 1, 'abc', (0, 1), [1,2,3], {'a':0, 'b':[1,2]}])
>>> print(F)
FrozenList([True, 1, 'abc', (0, 1), FrozenList([1, 2, 3]), FrozenDict({'a': 0, 'b': FrozenList([1, 2])})])
>>> FT = freeze((0,1,[1,2]))
>>> print(FT)
FrozenTuple((0, 1, FrozenList([1, 2])))

Thawing a frozen object returns the original mutable object:

>>> thaw(FD)
{'a': 1, 'b': 'qwe'}
>>> thaw(F)
[True, 1, 'abc', (0, 1), [1, 2, 3], {'a': 0, 'b': [1, 2]}]
>>> thaw(FT)
(0, 1, [1, 2])

24.1. Create your own frozen classes

>>> class Point:
...     def __init__(self, x, y):
...         self.x = x
...         self.y = y
...     def __repr__(self):
...         return f"Point({self.x}, {self.y})"
>>> class FrozenPoint(tuple):
...     _frozen_ = True
...     def __new__(self, point):
...         return tuple.__new__(FrozenPoint, (freeze(P.x), freeze(P.y)))
...     def _thaw_(self):
...         return Point(*self)
...     def __repr__(self):
...         return "FrozenPoint" + tuple.__repr__(self)
>>> Freezer[Point] = FrozenPoint
>>> P = Point(1.4, 2.7)
>>> P.y = 3.5
>>> FP = freeze(P)
>>> FP
FrozenPoint(1.4, 3.5)
>>> FP[0]
1.4
>>> thaw(FP)
Point(1.4, 3.5)

24.2. Classes defined in module freeze

class freeze.FrozenTuple(data, /)[source]

A frozen tuple

A FrozenTuple is a tuple where each of the items is frozen.

class freeze.FrozenList(data, /)[source]

A frozen list

class freeze.FrozenDict(data, /)[source]

A frozen dict

24.3. Functions defined in module freeze

freeze.frozen(obj)[source]

Check that an object is immutable

freeze.freezable(obj)[source]

Check if an object is freezable