Here's some code in a django tutorial that I'm going through. I've never come across the super function in python before and the way it's used here is different from the examples I've seen online. I.e., usually when you use super, don't you have multiple classes? It's in the last line: super(Snippet, self).save(force_insert, force_update)
Could you explain exactly what's going on there and what would be an alternative way to write that. It just seems like the save method is calling itself here?
下面是我正在学习的django教程中的一些代码。我以前从未在python中遇到过超函数,这里使用它的方式与我在网上看到的示例不同。即。,当你使用super的时候,你不是有很多类吗?它在最后一行:super(代码片段,self)。保存(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)
2 个解决方案
#1
25
super(Snippet, self)
causes Python to look in the MRO of the class of self (i.e. self.__class__.mro()
for the next class listed after Snippet
. It returns a super
object which acts as a proxy for that class. That is, calling a method on the super
object acts like calling that method on the class.
super(Snippet, self)使Python查找self类的MRO(例如,self.__class__. MRO(),以便查找片段后面列出的下一个类。它返回一个作为该类的代理的超对象。也就是说,在超对象上调用一个方法就像在类上调用那个方法一样。
super(Snippet, self).save(...)
calls that class's save
method, with self
bound to the first argument.
super(代码片段,self).save(…)调用该类的save方法,并将self绑定到第一个参数。
So super(Snippet, self).save(...)
will not call Snippet
's save
method; it will call some other class's save
method. It is tempting to think this "other class" is the "parent class" or "superclass" of Snippet
, that is, models.Model
, but that may not be true and it is absolutely wrong to apprehend super
this way. Which class super(Snippet, self)
ultimately represents depends on self
and in particular its class's MRO.
所以super(Snippet, self).save(…)不会调用Snippet的save方法;它将调用其他类的save方法。我们很容易认为这个“其他类”是Snippet的“父类”或“超类”,即模型。模型,但那可能不是真的,用这种方式理解超超是绝对错误的。类super(代码片段,self)最终表示的内容取决于self,特别是类的MRO。
A very good description of the MRO
and super
(complete with pictures!) can be found here.
可以在这里找到关于MRO和super(完整的图片!)的很好的描述。
#2
3
I won't explain again what unutbu explained on super classes, however you obtain the same effect with the following code :
我不会再解释unutbu在超类上的解释,但是你会得到同样的效果和下面的代码:
models.Model.save(self, force_insert, force_update)
This is NOT a better way to write it since, if you come to change the class inheritance by adding an intermediate class between Model and Snippet you would also have to change this line (which you would most likely forget). Anyway it's a good thing to know.
这并不是一种更好的编写方法,因为如果您想通过在Model和Snippet之间添加一个中间类来更改类继承,那么您还必须更改这一行(您很可能会忘记这一行)。不管怎样,这是件好事。
I can also add that the super instruction only works if the class you inherit from extends from object, otherwise you get an exception.
我还可以补充说,超级指令只在从object继承的类扩展时才有效,否则会出现异常。
#1
25
super(Snippet, self)
causes Python to look in the MRO of the class of self (i.e. self.__class__.mro()
for the next class listed after Snippet
. It returns a super
object which acts as a proxy for that class. That is, calling a method on the super
object acts like calling that method on the class.
super(Snippet, self)使Python查找self类的MRO(例如,self.__class__. MRO(),以便查找片段后面列出的下一个类。它返回一个作为该类的代理的超对象。也就是说,在超对象上调用一个方法就像在类上调用那个方法一样。
super(Snippet, self).save(...)
calls that class's save
method, with self
bound to the first argument.
super(代码片段,self).save(…)调用该类的save方法,并将self绑定到第一个参数。
So super(Snippet, self).save(...)
will not call Snippet
's save
method; it will call some other class's save
method. It is tempting to think this "other class" is the "parent class" or "superclass" of Snippet
, that is, models.Model
, but that may not be true and it is absolutely wrong to apprehend super
this way. Which class super(Snippet, self)
ultimately represents depends on self
and in particular its class's MRO.
所以super(Snippet, self).save(…)不会调用Snippet的save方法;它将调用其他类的save方法。我们很容易认为这个“其他类”是Snippet的“父类”或“超类”,即模型。模型,但那可能不是真的,用这种方式理解超超是绝对错误的。类super(代码片段,self)最终表示的内容取决于self,特别是类的MRO。
A very good description of the MRO
and super
(complete with pictures!) can be found here.
可以在这里找到关于MRO和super(完整的图片!)的很好的描述。
#2
3
I won't explain again what unutbu explained on super classes, however you obtain the same effect with the following code :
我不会再解释unutbu在超类上的解释,但是你会得到同样的效果和下面的代码:
models.Model.save(self, force_insert, force_update)
This is NOT a better way to write it since, if you come to change the class inheritance by adding an intermediate class between Model and Snippet you would also have to change this line (which you would most likely forget). Anyway it's a good thing to know.
这并不是一种更好的编写方法,因为如果您想通过在Model和Snippet之间添加一个中间类来更改类继承,那么您还必须更改这一行(您很可能会忘记这一行)。不管怎样,这是件好事。
I can also add that the super instruction only works if the class you inherit from extends from object, otherwise you get an exception.
我还可以补充说,超级指令只在从object继承的类扩展时才有效,否则会出现异常。