ActiveState Code

Recipe 576527: freeze(), make any object immutable


Calling freeze() on an object makes the object immutable, like const in C++. Useful if you want to make sure that a function doesn't mess with the parameters you pass to it.

Basic usage:

class Foo(object):
    def __init__(self):
        self.x = 1

def bar(f):
    f.x += 1

f = Foo()
bar(freeze(f)) #Raises an exception
Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
immutable_types = set((int, str))

class Frozen(object):
    def __init__(self, value):
        self._value = value

    def __getattribute__(self, name):
        if name == '_value': return super(Frozen, self).__getattribute__(name)
        v = getattr(self._value, name)
        return v if v.__class__ in immutable_types else freeze(v)
  
    def __setattr__(self, name, value):
        if name == '_value': super(Frozen, self).__setattr__(name, value)
        else: raise Exception("Can't modify frozen object {0}".format(self._value))
    
def freeze(value):
  return Frozen(value)

Comments

  1. 1. At 5:32 a.m. on 19 nov 2008, denis said:

    nice goal; unfortunately mutables down inside "immutables" are mutable --

    tup = ( [0] , )
    tup[0][0] += 1
    print tup  # ([1],)
    
    freeze( tup )
    tup[0][0] += 1
    print tup  # ([2],)
    

    (Imho "freeze" / static should be in the language, for programmer sanity. "class Employee: pass" is ridiculous, namedtuple / Record close but).

  2. 2. At 2:11 a.m. on 21 nov 2008, denis said:

    oops, should be "tup = freeze(tup)" -- my mistake, delete the previous comment

Sign in to comment