为了处理在各种现有答案中表达的所有问题,我建议采用以下方法:称之为saving
或modifying
,这是一个上下文管理器,该方法的入口设置了一个私有标志,表示修改正在进行;退出重置标志并执行保存;所有修改方法都检查f如果未设置,则会滞后并引发异常。例如,使用一个基类和save
方法,真正的子类必须重写:
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
使用例...:
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")
保证用户不会忘记打电话saving
也不意外以嵌套的方式调用它(这是所有这些例外的目的),并且在完成修改方法组时,只需调用save
一次,用一种方便的方式,并且我相当自然地说。
一些语法挑剔:短语“类方法”意味着一个用'@ classmethod'装饰的函数,用作类的方法而不是实例。你的问题应该只是说'修改方法'。 “自救”使得听起来像是在谈论保存方法,而不是实例;你应该说“保存'自我'”。最后,你让它听起来像方法应该被调用后再次调用。更好的可能是:“修改'self'的方法是否应该调用save()本身,还是应该save()之后被显式调用?” – Glyph 2010-06-26 19:52:07