我什么时候应该在python的Base类中使用关键字super?

时间:2016-12-01 05:24:44

标签: python django inheritance django-forms multiple-inheritance

我试图理解python中的this piece of code。根据我的理解,当您不想显式写入基类的名称时,super用于从派生类调用基类函数。但是如下所述,如果基类本身使用super来调用某个函数,这意味着什么呢?

class ReviewViewMixin(object):
    def dispatch(self, request, *args, **kwargs):
        # some code
        return super(ReviewViewMixin, self).dispatch(request, *args, **kwargs)


class ReviewCreateView(ReviewViewMixin, CreateView):
    # some code
    def dispatch(self, request, *args, **kwargs):
        super(ReviewCreateView, self).dispatch(request, *args, **kwargs)

我尝试创建几个像上面这样的示例类,但我得到了预期的“没有这样的参数”异常。

1 个答案:

答案 0 :(得分:3)

您会注意到您的班级ReviewCreateView两个(直接)基类。 super是必要的,以确保在这些基类的两个上调用dispatch方法。

每当创建一个类时,python会查看继承树并将其展平,从而创建一个名为"Method Resolution Order" (MRO)的东西。在这种情况下,您的MRO可能是 1

ReviewCreateView, ReviewViewMixin, CreateView, ..., object

super做什么检查当前的MRO,并在MRO的下一个类中调用该方法。您的调用堆栈将如下所示:

ReviewCreateView.dispatch (super) -> ReviewViewMixin.dispatch (super) -> CreateView.dispatch

现在请注意,如果ReviewViewMixin中没有super,那么调用堆栈就会以此结束。但是,由于它有一个super而MRO中的下一个类是CreateView,因此CreateView的调度方法也会被调用。

super真的很难理解 - 我建议阅读Raymond Hettinger的"super is Super"文章,了解一些想法和最佳实践。

1 您可以使用inspect.getmro(ReviewCreateView)或仅查看ReviewCreateView.__mro__

来检查MRO