当前位置: 首页 > news >正文

036.Python面向对象_self_cls_super

无奋斗不青春

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈
入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈
虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈
PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈
Oracle数据库教程:👉👉 Oracle数据库文章合集 👈👈
优 质 资 源 下 载 :👉👉 资源下载合集 👈👈

分隔线

Python面向对象_self_cls_super

    • self
    • cls
    • super

self


cls


super

  • 继承关系中,在低优先级类的方法中通过super调用高优先级类的方法

  • 概念

    • 是一个类,只有在新式类中有效
  • 作用

    • 起着代理的作用,沿着MRO链条,找到下一节点,去调用对应的方法
    • 在其他语言中会把super认定是父类,但是Python是支持多继承的,所以在Python中super与父类并没有直接的关系,完全是按照MRO链条来的
    • 在这里插入图片描述
  • 问题点

    • 沿着谁的MRO链条查找?
    • 找到谁的下一个节点?
    • 调用方法时,类方法、静态方法、实例方法的传参问题
  • 语法原理

    • 语法
      super(参数1[, 参数2])
      
    • 工作原理
      def super(cls, inst):mro = inst.__class__.mro()return mro[mro.index(cls) + 1]# inst.__class__            # 获取第二个参数inst对象对应的类对象
      # inst.__class__.mro()      # 获取对应类对象的mro链条,返回一个列表
      # mro示例:[<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class 'object'>]# mro.index(cls)            # 获取指定类对象在这个mro链条列表中的索引位置
      # mro.index(cls) + 1        # 获取指定类对象的下一个节点索引号
      # mro[mro.index(cls) + 1]   # 根据索引号获取mro链条列表中下一个节点的类对象
      
  • 问题解决

    • 沿着谁的MRO链条查找? ————> 参数2
    • 找到谁的下一个节点? ————> 参数1
    • 调用方法时,类方法、静态方法、实例方法的传参问题 ————> 使用参数2进行调用
  • 常用语法形式

    # 在Python2.2+
    super(type, obj)        # 一般调用其他类的实例方法,会把这个obj传递另外一个类的实例方法中的第一个参数
    super(type, type2)      # 一般调用其他类的类方法,会把这个type2传递另外一个类的类方法中的第一个参数cls# 只能在Python3+中使用,仅新式类可用
    super()                 # 仅仅适用于写在类定义的内部,会自动的根据当前所在的类和方法里面,取到对应的类名和方法的第一个参数自动填充进去
    
  • 示例1:调用实例方法

    class B(object):def __init__(self):self.b = 'b'class A(B):def __init__(self):super(A, self).__init__()# def super(cls, inst):#     mro = inst.__class__.mro()#     return mro[mro.index(cls) + 1]# 首先确定是要调用的B的__init__方法,先确定B是谁的下一级,B是A的下一级,所以第一个参数传A# 需要在这个mro链条中通过A的索引获取到下一级的索引,那么谁的mro链条中会有A呢?要么是A,要么是A的实例,或者是A的子类# 这里要调用的是B的__init__方法,这个__init__方法的参数需要一个类实例对象,所以我们可以通过A的实例(self)来获取mro链条# super函数的第二个参数会直接作为调用的实例方法的第一个参数传递过去,所以__init__方法后面可以不加self参数了self.a = 'a'a = A()
    print(a.__dict__)       # {'b': 'b', 'a': 'a'}
    
  • 示例2:调用类方法

    class B(object):@classmethoddef t1(cls):print(cls)print('t1')class A(B):@classmethoddef tt1(cls):super(A, cls).t1()print('tt1')# def super(cls, inst):#     mro = inst.__class__.mro()#     return mro[mro.index(cls) + 1]# 首先确定是要调用的B的t1()方法,先确定B是谁的下一级,B是A的下一级,所以第一个参数传A# 需要在这个mro链条中通过A的索引获取到下一级的索引,那么谁的mro链条中会有A呢?要么是A,要么是A的实例,或者是A的子类# 这里要调用的是B的t1()方法,这个t1(cls)方法的参数需要一个类对象,所以我们可以通过A这个类来获取mro链条# super函数的第二个参数会直接作为调用的类方法的第一个参数传递过去,所以super(A, cls).t1()方法后面可以不加cls参数了a = A()
    a.tt1()# 输出结果
    # <class '__main__.A'>      # 执行 super(A, cls).t1() 调用B内部的 t1(),打印cls,这里的cls就是super函数中给的第二个参数
    # t1                        # 执行 super(A, cls).t1() 调用B内部的 t1(),打印 't1'
    # tt1                       # 执行 print('tt1')
  • 示例3:调用静态方法

    class B(object):@staticmethoddef t1(n):print(n)print('t1')class A(B):@staticmethoddef tt1(name):super(A, A).t1(name)print('tt1')# def super(cls, inst):#     mro = inst.__class__.mro()#     return mro[mro.index(cls) + 1]# 首先确定是要调用的B的t1()方法,先确定B是谁的下一级,B是A的下一级,所以第一个参数传A# 需要在这个mro链条中通过A的索引获取到下一级的索引,那么谁的mro链条中会有A呢?要么是A,要么是A的实例,或者是A的子类# 这里要调用的是B的t1()方法,这个t1(n)方法的参数需要一个值,在静态方法中我们拿不到实例对象self,也没有cls,所以只能传A或者A的子类# B内部的t1(n)方法需要接收一个参数,所以super(A, A).t1(name)方法后面需要添加参数传递a = A()
    a.tt1('失心疯')# 输出结果
    # 失心疯
    # t1
    # tt1
    

相关文章:

  • ffmpeg常用命令
  • 倪海厦:教你正确煮中药,发挥最大药效
  • 别再写满屏的 try catch 了,教你如何统一处理异常!
  • uniapp 数组添加不重复元素
  • 【PHP】php发送邮箱验证码格式美化,样式美化
  • Shopify 开源 WebAssembly 工具链 Ruvy
  • MongoDB的条件操作符
  • mysql5.7安装详细教程
  • 【目标检测从零开始】torch实现yolov3数据加载
  • Tomcat管理功能使用
  • [Geek Challenge 2023] web题解
  • 德国进口高速主轴电机在机器人上的应用及选型方案
  • oops-framework框架 之 Excel转Json
  • LinuxShell的 中括号[], 双中括号[[]], 双小括号(()) 笔记231207
  • Java Web应用优化 认识软件设计分层架构
  • 分享一款快速APP功能测试工具
  • canvas 五子棋游戏
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • CSS相对定位
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • GraphQL学习过程应该是这样的
  • leetcode-27. Remove Element
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • oschina
  • SpiderData 2019年2月23日 DApp数据排行榜
  • Vue实战(四)登录/注册页的实现
  • 闭包--闭包作用之保存(一)
  • 等保2.0 | 几维安全发布等保检测、等保加固专版 加速企业等保合规
  • 对象管理器(defineProperty)学习笔记
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 官方解决所有 npm 全局安装权限问题
  • 马上搞懂 GeoJSON
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 区块链将重新定义世界
  • 深度学习在携程攻略社区的应用
  • 一个项目push到多个远程Git仓库
  • 摩拜创始人胡玮炜也彻底离开了,共享单车行业还有未来吗? ...
  • 如何用纯 CSS 创作一个货车 loader
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • #HarmonyOS:基础语法
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • (160)时序收敛--->(10)时序收敛十
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (C++20) consteval立即函数
  • (HAL)STM32F103C6T8——软件模拟I2C驱动0.96寸OLED屏幕
  • (java)关于Thread的挂起和恢复
  • (代码示例)使用setTimeout来延迟加载JS脚本文件
  • (第8天)保姆级 PL/SQL Developer 安装与配置
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (回溯) LeetCode 78. 子集
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (七)c52学习之旅-中断
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (三)mysql_MYSQL(三)