Метод класса изменения должен сохранить себя или explicity быть названным после того, как метод назовут?

Предположим, что класс имеет метод, который изменяет, это - внутренности. Тот вызов метода должен экономить на себе прежде, чем возвратиться, или сохранение нужно оставить вызывающей стороне явно сохранить после того, как метод изменения назвали?

Пример:

Явно вызов сохраняет:

class Bar(models.Model):
    def set_foo(self, foo):
        self.foo = foo

bar = Bar()
bar.set_foo("foobar")
bar.save()

или разрешение метода звонить сохраняет:

class Bar(models.Model):
    def set_foo(self, foo):
        self.foo = foo
        self.save()

bar = Bar()
bar.set_foo("foobar")

Я работаю с django, но я задавался вопросом, была ли лучшая практика в django или в целом для этой ситуации.

8
задан Simplecoder 26 June 2010 в 19:14
поделиться

4 ответа

Пользователь вашего API может забыть вызвать .save (), а затем ошибиться. Так что я думаю, что лучше позвонить и сэкономить для него. Для случаев, подобных тем, которые упоминает Даслч, если это имеет смысл, вы можете определить:

def set_foo(self, foo, skip_save=False):
    self.foo = foo
    if not skip_save:
        self.save()

, чтобы пользователь мог, если он желает (и явно заявляет об этом), избежать сохранения.

2
ответ дан 5 December 2019 в 22:16
поделиться

Пользователь вашего API может захотеть сделать несколько изменений, сохранение объекта после каждого изменения - это не очень хорошо, так что нет, не вызывайте save в вашем методе.

3
ответ дан 5 December 2019 в 22:16
поделиться

На самом деле, я согласен и с Офри, и с Даслчем ... в зависимости от того, какой сегодня день недели. Если это всего лишь одна из многих процедур модификации, которые вы можете применить к конкретному объекту, то будет довольно дорого, если каждая из них будет делать свое собственное сохранение. С другой стороны, если это редкое, самодостаточное событие, вы хотите сохранить, потому что это может быть неочевидно для вызывающего абонента (т. Е. Для кого-то, кроме вы , что это необходимо сделать. .

Например, тегирование событий (которые в любом случае используют ManyToMany) не должно требовать дополнительного save () со стороны программистов.

1
ответ дан 5 December 2019 в 22:16
поделиться

Для решения всех вопросов, выраженных в различных существующих ответах, я предлагаю следующий подход: сделайте метод, назовите его, скажем, сохранение или изменение, который является менеджером контекста. При входе в этот метод устанавливается приватный флаг, который говорит, что идет модификация; при выходе флаг сбрасывается и выполняется сохранение; все модифицирующие методы проверяют флаг и вызывают исключение, если он не установлен. Например, используя базовый класс и метод 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")

Это гарантирует, что пользователь не забудет вызвать save и не вызовет его случайно вложенным способом (именно для этого и предназначены все эти исключения), а вызовет save только один раз, когда группа модифицирующих методов будет завершена, удобным и, я бы сказал, довольно естественным способом.

0
ответ дан 5 December 2019 в 22:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: