[pyar] Como hacer un objeto inmutable

Claudio Freire klaussfreire en gmail.com
Dom Nov 6 20:37:08 ART 2011


2011/10/28 Alejandro Santos <listas en alejolp.com>:
> Sin usar tuplas, namedtuples[1] ni extensiones en C, ¿cómo puedo hacer
> mi propio tipo de datos cuyas instancias sean inmutables garantizadas
> por el lenguaje? ¿es posible hacerlo usando clases, magia de
> decoradores y nada más?

def ReadOnlyPoint(xx,yy):
    class ReadOnlyPoint(object):
         x = xx
         y = yy
         __slots__ = ('x','y')
    return ReadOnlyPoint()

Es lo más cerca que llegué.
Me pareció interesante.
Es atacable con lo que propone Daniel, pero fuera de eso, da fuertes garantías:

>>> p = ReadOnlyPoint(1,2)
>>> p.x
1
>>> p.y
2
>>> del p.x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'ReadOnlyPoint' object attribute 'x' is read-only
>>> del p.y
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'ReadOnlyPoint' object attribute 'y' is read-only
>>> p.x = 4
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'ReadOnlyPoint' object attribute 'x' is read-only
>>> class A:pass
...
>>> p.__bases__ = (A,)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'ReadOnlyPoint' object has no attribute '__bases__'
>>> p.__class__ = A
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __class__ must be set to new-style class, not 'classobj' object
>>> class A(object): pass
...
>>> p.__class__ = A
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __class__ assignment: 'ReadOnlyPoint' object layout differs from 'A'
>>> class A(object):
...    __slots__ = ('x','y')
...
>>> p.__class__ = A
>>> p.x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: x
>>> p.x = 4
>>>



More information about the pyar mailing list