Para tratar todos los problemas expresados en varias respuestas existentes, sugiero el siguiente enfoque: crear un método, llamarlo decir saving
o modifying
, que es un administrador de contexto. La entrada a ese método establece una bandera privada que dice que la modificación está en progreso; la salida restablece los indicadores y realiza el guardado; todos los métodos de modificación verifican rezagar y generar una excepción si no se establece. Por ejemplo, el uso de una clase base y un método que save
subclases reales deben prevalecer:
import contextlib
class CarefullyDesigned(object):
def __init__(self):
self.__saving = False
def _save(self):
raise NotImplementedError('Must override `_save`!')
def _checksaving(self):
"Call at start of subclass `save` and modifying-methods"
if not self.__saving: raise ValueError('No saving in progress!')
@contextlib.contextmanager
def saving(self):
if self.__saving: raise ValueError('Saving already in progress!')
self.__saving = True
yield
self._save()
self.__saving = False
Ejemplo del uso ...:
class Bar(models.Model, CarefullyDesigned):
def __init__(self, *a, **k):
models.Model.__init__(self, *a, **k)
CarefullyDesigned.__init__(self)
def _save(self):
self._checksaving()
self.save()
def set_foo(self, foo):
self._checksaving()
self.foo = foo
def set_fie(self, fie):
self._checksaving()
self.fie = fie
bar = Bar()
with bar.saving():
bar.set_foo("foobar")
bar.set_fie("fo fum")
Esto garantiza que el usuario no se olvide de llamar saving
ni accidentalmente llámalo de forma anidada (ese es el propósito de todas esas excepciones), y llama al save
solo una vez cuando el grupo de métodos modificadores esté hecho, de una forma práctica y, diría, bastante natural.
Algunos nitidez de gramática: La frase "método de clase" implica una función decorada con '@ classmethod', que se utiliza como un método en la clase en lugar de una instancia. Tu pregunta probablemente debería simplemente decir 'método de modificación'. 'guardarse' hace que parezca que estás hablando de guardar el método, en lugar de la instancia; usted debe decir "guardarse" '. Finalmente, lo hace sonar como si el método se llamara nuevamente después de ser llamado.Mejor podría ser: "¿Debería un método que modifica 'auto' llamar a save() en sí mismo, o debería guardar() explícitamente después?" – Glyph