为了账号安全,请及时绑定邮箱和手机立即绑定

python中的super怎么用?

标签:
Python

面向对象有这个强大特点和作用, 著名的三大特点:封装, 继承, 多态

这篇博客写的是super()的简单理解和使用

今天在读restframework的源码的时候, 发现源码中使用了super, 依以此为入口, 重写了django的as_view()

在代码执行的过程中既执行了自己的as_view()有执行了django的as_view()

 

super()能做什么?

之前的理解就是, 使用super()可以在子类中调用父类的方法或属性, 可能你会说, 子类本来就可以调用父类中所有非私有的属性或方法,

而我现在说的是, 当子类中实现了某个方法, 父类中也有这个方法, 当你调用这个方法时, 既想执行子类的又想执行父类的, 在这种情况下

就可以使用super()

 

super()怎么用的

class A(object):    
def __init__(self, name, age):
        self.name = name
        self.age = age        
        print("class A")class B(A):    
        def __init__(self, name, age):
        super().__init__(name, age)        
        print("class B")class C(B):    
        def __init__(self, name, age):        
        # 方式一
        super().__init__(name, age)        
        # 相当于 super(C, self).__init__(name, age)
        # 默认是从当前类的父类开始往上找__init__()

        # 方式二
        # 指定从当前类的某个父类中开始往上找
        super(B, self).__init__(name, age)        
        print("class C")


c = C("sath", 37)


 

定义了三个类, 继承关系为 C 继承 B 继承 A

定C类进行实例化的时候, 要先执行__init__()[__new__先不说], 

C类中有__init__()方法, 所以就会执行C类中的__init__()

但是在C类自己的__init__()中却使用了super(). 并且是   点.__init__()

这就表示要去执行父类的__init()方法

super()有两中使用方法

方法一

super().__init__()

默认执行当前类的父类中的方法, 并且将当前类的实例对象self传了进去

其实就相当于super(C, self).__init__()

父类中的__init__(self), 中的self就是super()传进去的self, 

 

方法二

super(B, self)>__init__()

其实和方法一一样, 就是指定的父类不一样了, 你可以指定执行那个父类的__init__()

前提是必须是当前这个类的父类

这样执行的执行的话, 参数就会灵活很多

 

restframework中对super()的应用实例

先来看一下源码

@classmethod    def as_view(cls, **initkwargs):        
if isinstance(getattr(cls, 'queryset', None), models.query.QuerySet):            
def force_evaluation():                raise RuntimeError(                    
'Do not evaluate the `.queryset` attribute directly, '
                    'as the result will be cached and reused between requests. '
                    'Use `.all()` or call `.get_queryset()` instead.'
                )
            cls.queryset._fetch_all = force_evaluation

        view = super(APIView, cls).as_view(**initkwargs)
        super().__init__()
        view.cls = cls
        view.initkwargs = initkwargs        
        return csrf_exempt(view)


现在就来看这行代码 view = super(APIView, cls).as_view(**initkwargs)

写了一个CBV, 视图继承了APIView

当请求进来之后, 进行路由匹配然后调用视图函数, CBV会执行as_view()

我是的路由是这样式的

url(r'^auth/', views.AuthView.as_view())

AuthView就是视图类, 继承了APIView, 当调用as_view()时, 先去自己的类中找as_view, 发现没有, 然后去父类中找

上面的as_view()代码就是APIViwe类中的as_view(), APIView其实也继承了View

发现as_view()是一个类方法, 怪不得在路由中使用类去调用呢, 这个样就能得到视图类的类空间了

因为在View中需要用视图类, 然后对视图类进行了实例化, 通过这个实例在加上反射获取和用户请求方式同名的函数并执行

上面就是super()在restframework中的应用

作者:王剑威

原文链接:https://www.cnblogs.com/594504110python/p/10181538.html

 


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消