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 immutablethaw()
: make a frozen objects mutable againfrozen()
: 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)