privadas - Formas de hacer una clase inmutable en Python.
programacion orientada a objetos python ejemplos pdf (3)
Estoy haciendo un poco de computación distribuida en la que varias máquinas se comunican bajo el supuesto de que todas tienen versiones idénticas de varias clases. Por lo tanto, parece ser un buen diseño para hacer estas clases inmutables; no en el sentido de que debe frustrar a un usuario con malas intenciones, solo lo suficientemente inmutable para que nunca sea modificado por accidente.
¿Cómo voy a hacer esto? Por ejemplo, ¿cómo implementaría una metaclase que hace que la clase que la usa sea inmutable después de su definición?
>>> class A(object):
... __metaclass__ = ImmutableMetaclass
>>> A.something = SomethingElse # Don''t want this
>>> a = A()
>>> a.something = Whatever # obviously, this is still perfectly fine.
Los métodos alternativos también están bien, como un decorador / función que toma una clase y devuelve una clase inmutable.
No pierdas el tiempo en clases inmutables.
Hay cosas que puedes hacer que son mucho más simples que perder el tiempo intentando crear un objeto inmutable.
Aquí hay cinco técnicas separadas. Puedes elegir y elegir entre ellos. Cualquiera trabajará. Algunas combinaciones funcionarán, también.
Documentación. En realidad, no olvidarán esto. Dales crédito.
Prueba de unidad. Simule los objetos de su aplicación con un simulacro simple que maneja
__setattr__
como una excepción. Cualquier cambio en el estado del objeto es un fallo en la prueba de la unidad. Es fácil y no requiere ninguna programación elaborada.Reemplace
__setattr__
para generar una excepción en cada intento de escritura.collections.namedtuple
. Son inmutables fuera de la caja.collections.Mapping
. Es inmutable, pero necesitas implementar algunos métodos para que funcione.
Si el viejo truco de usar __slots__
no se ajusta a usted, esto o alguna variante de eso puede hacerlo: simplemente escriba el método __setattr__
de su metaclase para que sea su guardia. En este ejemplo, evito que se asignen nuevos atributos, pero permito la modificación de los existentes:
def immutable_meta(name, bases, dct):
class Meta(type):
def __init__(cls, name, bases, dct):
type.__setattr__(cls,"attr",set(dct.keys()))
type.__init__(cls, name, bases, dct)
def __setattr__(cls, attr, value):
if attr not in cls.attr:
raise AttributeError ("Cannot assign attributes to this class")
return type.__setattr__(cls, attr, value)
return Meta(name, bases, dct)
class A:
__metaclass__ = immutable_meta
b = "test"
a = A()
a.c = 10 # this works
A.c = 20 # raises valueError
Si no te importa reutilizar el trabajo de otra persona:
http://packages.python.org/pysistence/
Estructuras de datos persistentes inmutables (en el sentido funcional, no de escritura a escritorio).
Incluso si no los usa tal como están, el código fuente debería proporcionar alguna inspiración. Su clase expando, por ejemplo, toma un objeto en su constructor y devuelve una versión inmutable de él.