How to make an immutable instance

Peter Otten __peter__ at web.de
Thu Jun 17 20:55:35 CEST 2004


Batista, Facundo wrote:

> I'm working on Decimal, and one of the PEP requests is Decimal to be
> immutable.
> 
> The closer I got to that is (in short):
> 
> class C(object):
> 
>     __slots__ = ('__x',)
> 
>     def __init__(self, value):
>         self.__x = value
> 
>     def getx(self):
>         return self.__x
> 
>     x = property(getx)

> The problem is that you actually could, if you take the effort, to rebind
> the __x name.
> 
> So, if you use this "immutable" class in a dict, and then you (on purpose)
> modify it, you'll have different hashes.

I don't think this will be a problem in practice. If you are determined,
there are easier ways to break your program :-)

> Said that, how safer is this approach? Is there a better way?

An alternative would be to subclass tuple:

>>> class C(tuple):
...     def __new__(cls, x):
...             return tuple.__new__(cls, (x,))
...     x = property(lambda self: self[0])
...
>>> c = C(1)
>>> c.x
1

Not necessarily better, as 

>>> isinstance(c, tuple)
True

and a Decimal pretending to be a sequence type may cause greater
inconveniences than the "weak immutability" you currently have.

> Thank you all!

Thank you for your work to further improve Python.

Peter




More information about the Python-list mailing list