美文网首页
mixin类中super()到底继承谁的方法?

mixin类中super()到底继承谁的方法?

作者: warmsirius | 来源:发表于2019-08-16 18:59 被阅读0次

写在前面

参考博客

回到 LoginRequiredMixin 例子中来

涉及到的三个类

  • LoginRequiredMixin(实现用户登录装饰器功能)
  • View类(Django部分源码)
  • UserInfoView类(继承 LoginRequiredMixin、View类)
from django.contrib.auth.decorators import login_required

# LoginRequiredMixin 类
class LoginRequiredMixin(object):
    @classmethod
    def as_view(cls, **initkwargs):
        # 调用父类的as_view
        view = super(LoginRequiredMixin, cls).as_view(**initkwargs)
        return login_required(view)


# View类
class View:
    ...

    @classonlymethod
    def as_view(cls, **initkwargs):
        """Main entry point for a request-response process."""
        for key in initkwargs:
            if key in cls.http_method_names:
                raise TypeError("You tried to pass in the %s method name as a "
                                "keyword argument to %s(). Don't do that."
                                % (key, cls.__name__))
            if not hasattr(cls, key):
                raise TypeError("%s() received an invalid keyword %r. as_view "
                                "only accepts arguments that are already "
                                "attributes of the class." % (cls.__name__, key))
        ...


# UserInfoView类
class UserInfoView(LoginRequiredMixin, View):
    '''用户中心-信息页'''
    def get(self, request):
        '''显示'''
        # page = 'user'
        return render(request, 'df_user/user_center_info.html', {'page': 'user'})

提出问题

从上面可以看出,我们的 LoginRequiredMixin 继承的是object,但是object并没有as_view()方法,那么 LoginRequiredMixin 究竟调用了谁的as_view 方法呢?

问题解释

在多继承的环境下,super() 有相对来说更加复杂的含义。它会查看你的继承链,使用一种叫做 Methods Resolution Order(方法解析顺序) 的方式,来决定调用最近的继承父类的方法。

LoginRequiredMixin.as_view()的调用行为:

  • UserInfoView.as_view() 方法被解析为 LoginRequiredMixin.as_view() 方法的调用。因为对于 UserInfoView 类来说,在继承链上的两个父类,LoginRequiredMixin 和 View 来说,LoginRequiredMixin是最近的,因此调用 LoginRequiredMixin 的 as_view 方法

  • LoginRequiredMixin.as_view() 方法调用了 super().as_view(),这一行代码按照刚才的解释,查看 UserInfoView 的继承链,是应该调用 View 类的 as_view() 方法的。这一步是相对来说比较难以理解的。

LoginRequiredMixin调用解释

  • 当 LoginRequiredMixin.as_view() 中调用了 super().as_view() 的时候,它会 尝试去寻找属于当前类的继承链

  • 而这个当前类是什么类呢?不是 LoginRequiredMixin 类,而是 UserInfoView 类, UserInfoView 类的继承连是 LoginRequiredMixin 然后是 View 类的 as_view() 方法。

总结

  • 简单记住:self.method() 将会先在当前类中查看 method() 方法,如果没有,就在继承链中进行查找,查找顺序就是你继承的顺序从左到右,直到 method() 方法被找到。

  • super().method() 与 self.method() 是差不多的,只是 super().method() 需要跳过当前类而已。

  • Mixin 类总是需要与其他类混合来加强其他类,可以大大简化和方便我们的代码的开发过程。

相关文章

  • mixin类中super()到底继承谁的方法?

    写在前面 在上一篇 mixin类实现用户登录装饰器中遗留了一个问题,LoginRequiredMixin中的sup...

  • JavaScript零散知识点

    继承 super 在子类中调用super,会调用父类的方法; 不用super,则会覆盖父类的方法。调用本类中的方法。

  • 多继承以及MRO顺序

    1、单独调用父类的方法 2、多继承中super调用所有父类的被重写方法 3、单继承中super() 总结 supe...

  • python中super的使用

    super的简单用法 多继承中super的使用   super简单的说是调用父类的方法,不管是父类的初始化方法还是...

  • ES6学习笔记(二):教你玩转类的继承和类的对象

    继承 程序中的继承: 子类可以继承父类的一些属性和方法 super关键字 super关键字用于访问和调用对象父类上...

  • 1 es6类和对象 2019-12-12

    1.创建类和对象 2.类中添加方法 3.类的继承 4.super关键字 子类继承父类方法

  • java面向对象

    方法重载 方法重写 继承父类( 关键字: super、extends) super 关键字1.用super调用父类...

  • 原型

    class 和 继承 子类通过extends 和super 继承父类中的属性和方法Student和Tearch...

  • typescript中的类

    ts中如何定义类 ts中实现继承 extends super 继承 父类和子类有同样的方法的话,首先在子类里找,找...

  • super() 的入门使用

    原文出处: geekvi super() 的入门使用 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法...

网友评论

      本文标题:mixin类中super()到底继承谁的方法?

      本文链接:https://www.haomeiwen.com/subject/ojaqsctx.html