这是我正在经历的django教程中的一些代码。我以前从来没有遇到python中的超级函数,它在这里使用的方式与我在网上看到的例子不同。即,通常当你使用超级时,你不是有多个班级吗?它在最后一行:super(Snippet, self).save(force_insert, force_update)
你能解释一下那里发生了什么,以及另一种写作方式。看起来似乎保存方法在这里调用自己?
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)
答案 0 :(得分:26)
super(Snippet, self)
会导致Python查看自我类MRO(self.__class__.mro()
以查找Snippet
之后列出的 next 类。它返回一个super
对象,它充当该类的代理。也就是说,调用super
对象上的方法就像在类上调用该方法一样。
super(Snippet, self).save(...)
调用该类的save
方法,self
绑定到第一个参数。
因此super(Snippet, self).save(...)
不会调用Snippet
的{{1}}方法;它将调用其他类的save
方法。很容易认为这个“其他类”是save
的“父类”或“超类”,也就是说,
Snippet
,但这可能不是真的,以这种方式逮捕models.Model
是完全错误的。哪个类super
最终代表取决于super(Snippet, self)
,特别是其类的MRO。
可以找到self
和MRO
(包括图片!)的非常好的描述here。
答案 1 :(得分:4)
我不会再解释unutbu在超类上解释的内容,但是使用以下代码获得相同的效果:
models.Model.save(self, force_insert, force_update)
这不是更好的编写方式,因为如果你通过在Model和Snippet之间添加一个中间类来改变类继承,你也必须改变这一行(你很可能会忘记)。无论如何,要知道这是件好事。
我还可以补充一点,只有你继承的类从object扩展,super指令才有效,否则会出现异常。