澄清/何时/何地在django/python中使用super

Shi*_*dla 3 python forms django super models

实际上我们知道super用于查找"父类"并返回其对象,例如/ usingself.__class__.__mro__

我很困惑的是什么时候使用它?

假设我们有一个示例模型代码,如下所示

VERSION_1

class Example(models.Model):
    name = models.CharField()
    age  = models.IntegerField()

    def save(self, **args, **kwargs):
        obj = super(Example, self).save(self, **args, **kwargs)
        obj.name = "name changed"
        obj.age = "age changed"
        return obj
Run Code Online (Sandbox Code Playgroud)

VERSION_2

class Example(models.Model):
    name = models.CharField()
    age  = models.IntegerField()

    def save(self, **args, **kwargs):
        self.name = "name changed"
        self.age = "age changed"
        obj = super(Example, self).save(self, **args, **kwargs)
        return obj
Run Code Online (Sandbox Code Playgroud)

所以我们可以在上面观察

version_1中,我先调用super并对字段进行了修改并返回了obj

在版本_2中,我修改了字段,之后调用了super并返回了obj

那么在修改字段之前和之后调用super时会发生什么?

最后我想知道/确认的是

  • 在django表格/模型中使用/为什么精确超级.
  • 在django/python中使用它们的确切概念是什么(如果我理解错了).

Jan*_*nis 13

你的Example类是它的子类Model.这意味着,它Example继承了所有函数Model.

请看以下内容:

class Example():
    pass

example = Example()
#let's try to save it
example.save()

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: Example instance has no attribute 'save'
Run Code Online (Sandbox Code Playgroud)

现在继承.

class Parent():
    def save(*args, **kwargs):
        print "saving now"

class Example(Parent):
    pass

example = Example()
#since Example has no save method, it inherits the Parent's save method.
example.save()
"saving now"
Run Code Online (Sandbox Code Playgroud)

如果覆盖Example类中的save()方法,则不会调用Parent的save方法.

   class Example(Parent):
        def save(self, *args, **kwargs):
            print "i know how to save on my own now"

   example = Example()
   example.save()
   "i know how to save on my own now"
Run Code Online (Sandbox Code Playgroud)

如果您选择调用super,则调用Parent的save函数以及您自己的save()实现.

   class Example(Parent):
         def save(self, *args, **kwargs):
              super(Example, self).save(*args, **kwargs)
              print "i know how to save on my own now"

   example = Example()
   example.save()
   "saving now" #from parent
   "i know how to save on my own" #from example
Run Code Online (Sandbox Code Playgroud)

这同样适用于您继承的所有djangos类.实际上,实施更复杂.您可以在github上查看模型定义.

如果您感到激动,可以通过本次演讲深入了解django ORM


sie*_*z0r 5

我相信这个问题不是特定于 Django 的,因此我将尝试以通用的方式解释它。

super 的实用性在于您不需要指定要调用哪个基类(这也可能是一个缺点,因为 mro 定义了调用什么基类)。

我使用 super 创建 mixin(SO 上有一个很好的答案,描述了 mixin 是什么)。一个使用 super 的例子:

class LemonMixin(object):
    def tastes_like(self):
        return super(LemonMixin, self).tastes_like() + ' and lemon'

class Cola(object):
    def tastes_like(self):
        return 'sugar'

class ColaLemon(LemonMixin, Cola):
    pass

drink = ColaLemon()
drink.tastes_like()  # returns 'sugar and lemon'
Run Code Online (Sandbox Code Playgroud)

mixin 与 aplied 类无关,因此它可以使用 super 来使用 mro 来调用基类。

何时调用 super 完全取决于您。例如,如果您想检查安全性,请在安全性检查后调用 super。如果您想在某事完成时触发事件,您可能需要在触发事件之前调用 super。;-)