использование супер функции python в модели django

вот некоторый код в учебнике django, который я прохожу. Я никогда не сталкивался с супер-функцией в python раньше, и способ ее использования здесь отличается от примеров, которые я видел в интернете. То есть, обычно, когда вы используете super, разве у вас нет нескольких классов? Это в последней строке: super(Snippet, self).save(force_insert, force_update) Не могли бы вы объяснить, что именно там происходит и что было бы альтернативным способом написать это. Просто кажется, что метод save вызывает себя здесь?

class Snippet(models.Model):
    title = models.CharField(max_length=255)
    language = models.ForeignKey(Language)
    author = models.ForeignKey(User)
    description = models.TextField()
    description_html = models.TextField(editable=False)
    code = models.TextField()
    highlighted_code = models.TextField(editable=False)
    tags = TagField()
    pub_date = models.DateTimeField(editable=False)
    updated_date = models.DateTimeField(editable=False)

    class Meta:
        ordering = ['-pub_date']

    def __unicode__(self):
        return self.title

    def save(self, force_insert=False, force_update=False):
        if not self.id:
            self.pub_date = datetime.datetime.now()
        self.updated_date = datetime.datetime.now()
        self.description_html = markdown(self.description)
        self.highlighted_code = self.highlight()
        super(Snippet, self).save(force_insert, force_update)

2 ответов


super(Snippet, self) заставляет Python смотреть в MRO класса " я " (то есть self.__class__.mro() на далее класса, указанного после Snippet. Он возвращает super объект, который действует как прокси для этого класса. То есть вызов метода на super object действует как вызов этого метода в классе.

super(Snippet, self).save(...) называет этот класс save способ, с self привязан к первому аргументу.

так super(Snippet, self).save(...) не буду называть Snippet ' s save метод; он вызовет какой-то другой класс save метод. Заманчиво думать, что этот " другой класс "является" родительским классом "или" суперклассом"Snippet, то есть, models.Model, но это может быть неправдой, и совершенно неправильно понимать super этот путь. Какой класс super(Snippet, self) в конечном счете, представляет зависит от self и, в частности, его класс MRO.

очень хорошее описание MRO и super (в комплекте с фотографиями!) можно найти здесь.


Я не буду снова объяснять, что unutbu объяснил на супер классах, однако вы получаете тот же эффект со следующим кодом:

models.Model.save(self, force_insert, force_update)

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

Я также могу добавить, что супер инструкция работает только если класс, который вы наследуете от extends from object, иначе вы получаете исключение.