Si desea una clase con atributos de "abajo bloqueado" ejemplo, no es difícil de hacer uno, por ejemplo:
class LockedDown(object):
__locked = False
def __setattr__(self, name, value):
if self.__locked:
if name[:2] != '__' and name not in self.__dict__:
raise ValueError("Can't set attribute %r" % name)
object.__setattr__(self, name, value)
def _dolock(self):
self.__locked = True
class Example(LockedDown):
def __init__(self):
self.mistakes = 0
self._dolock()
def onemore(self):
self.mistakes += 1
print self.mistakes
def reset(self):
self.mitsakes = 0
x = Example()
for i in range(3): x.onemore()
x.reset()
Como se verá, las llamadas a x.onemore
funcionan bien, pero reset
genera una excepción debido a la ortografía incorrecta del atributo como mitsakes
. Las reglas de participación aquí son que __init__
debe establecer todos los atributos a los valores iniciales, luego llame al self._dolock()
para prohibir cualquier adición adicional de atributos. Expongo los atributos "súper privados" (que comienzan con __
), que estilísticamente deberían usarse muy raramente, para roles totalmente específicos, y con un alcance extremadamente limitado (por lo que es trivial detectar errores tipográficos en la inspección súper cuidadosa que se necesita) de todos modos para confirmar la necesidad de super-privacidad), pero esa es una elección estilística, fácil de revertir; de manera similar para la opción de hacer que el estado bloqueado sea "irreversible" (por medios "normales", es decir, que requieren una solución muy explícita para eludir).
Esto no se aplica a otros tipos de nombres, como los locales de función; de nuevo, no es gran cosa, porque cada función debe ser muy pequeña, y es un alcance totalmente autónomo, trivialmente fácil de inspeccionar (si escribes funciones de 100 líneas, tienes otros problemas serios ;-).
¿Vale la pena la molestia? No, porque las pruebas de unidades semi-decentes obviamente deberían detectar todos los errores tipográficos con la mayor facilidad, como un efecto colateral natural del ejercicio total de la funcionalidad de la clase. En otras palabras, no es necesario tener más pruebas de unidad solo para captar los errores tipográficos: la unidad necesita pruebas de todos modos para detectar errores semánticos triviales (uno por uno, +1 donde significa -1, etc. ., etc.) también detectará todos los errores tipográficos.
Robert Martin y Bruce Eckel tanto articulado este punto hace 7 años en artículos separados e independientes - Blog de Eckel está temporalmente fuera de este momento, pero Martín del derecho here, y cuando el sitio de Eckel revive el artículo debe ser here. La tesis es polémica (Jeff Attwood y sus comentaristas lo debaten here, por ejemplo), pero es interesante observar que Martin y Eckel son expertos bien conocidos de lenguajes estáticos como C++ y Java (aunque con relaciones amorosas, respectivamente, con Ruby y Python), y están lejos de ser los únicos que han descubierto la importancia de las pruebas unitarias ... y de cómo un buen conjunto de pruebas unitarias, como efecto colateral, hace que la rigidez de un lenguaje estático sea redundante.
Por cierto, una forma de comprobar sus suites de prueba es la "inyección de error": revise sistemáticamente la base de código introduciendo una ortografía incorrecta: ejecute las pruebas para asegurarse de que fallen, si no agregan una que falla, corrige el error de ortografía, repite. Se puede automatizar bastante bien (no la parte de "agregar una prueba", sino la búsqueda de errores potenciales que no están cubiertos por el paquete), al igual que otras formas de inyecciones de error (cambia cada entero constante, uno por uno, para uno más, y uno menos; cambie cada <
a <=
etc; cambie cada condición if
y while
a su inversa; ...), mientras que otras formas de inyección de errores requieren mucha más sabiduría humana. Desafortunadamente, no conozco las suites disponibles públicamente de marcos de inyección de errores (para cualquier idioma), podría ser un proyecto de código abierto genial ;-).
"Por qué Python te fuerza" ... "no puede causar errores" Esta es la definición misma de "subjetivo y argumentativo". Yo voté por cerrar. – balpha
@balpha considere aprender qué significan las palabras "subjetivo" y "argumentativo", ya que los ejemplos que cita son el * exactamente opuesto * de ambos. – hobbs
@hobbs Estoy hablando de la definición del * motivo cercano * "subjetivo y argumentativo" (tenga en cuenta el * solo * par de comillas alrededor de ambas palabras). Es imposible responder objetivamente a esta pregunta [ejemplo 2], y la pregunta fue hecha de una manera polémica y de confrontación [ejemplo 1]. – balpha