これが私が経験している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)
super(Snippet, self)
により、Pythonは自己のクラスの [〜#〜] mro [〜#〜] を調べます(つまり、self.__class__.mro()
Snippet
の後にリストされているnextクラスの場合。プロキシとして機能するsuper
オブジェクトを返します。つまり、super
オブジェクトでメソッドを呼び出すことは、クラスでそのメソッドを呼び出すことと同じように機能します。
super(Snippet, self).save(...)
は、そのクラスのsave
メソッドを呼び出し、self
を最初の引数にバインドします。
したがって、super(Snippet, self).save(...)
はSnippet
のsave
メソッドを呼び出しません。他のクラスのsave
メソッドを呼び出します。この「他のクラス」がSnippet
の「親クラス」または「スーパークラス」、つまり_models.Model
_であると考えたくなりますが、それは真実ではない可能性があり、理解することは絶対に間違っています。 super
このように。 super(Snippet, self)
が最終的に表すクラスは、self
、特にそのクラスのMROによって異なります。
MRO
とsuper
(写真付き!)の非常に良い説明が見つかります ここ 。
Unutbuがスーパークラスで説明したことを再度説明することはしませんが、次のコードで同じ効果が得られます。
models.Model.save(self, force_insert, force_update)
ModelとSnippetの間に中間クラスを追加してクラスの継承を変更する場合は、この行も変更する必要があるため、これは適切な記述方法ではありません(おそらく忘れてしまいます)。とにかく知っておくのは良いことです。
スーパー命令は、継承元のクラスがオブジェクトから拡張されている場合にのみ機能することも付け加えます。そうでない場合は、例外が発生します。