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

简介Python之super的用法及原理

1. super()的功能

看下面代码:

classB1(object):def__init__(self):self.b1=10classB2(object):def__init__(self):self.b2=20classS1(B1,B2):def__init__(self):B1.__init__(self)B2.__init__(self)self.s1=30if__name__=="__main__":mys1=S1()printmys1.b1,mys1.b2,mys1.s1# 10 20 30

以上是Python2.2之前的写法。
此时,如要将S1的父类B2改成B3,则__init__()中所有和B2相关的都要改成B3的;
并且,由以上也能看出,所有父类的__init__()都要显式地列在S1的__init__()中。

看Python2.2及其之后的写法(Python2.2引入了super())

classB1(object):def__init__(self):super(B1,self).__init__()self.b1=10classB2(object):def__init__(self):super(B2,self).__init__()self.b2=20classS2(B1,B2):def__init__(self):super(S2,self).__init__()self.s2=30if__name__=="__main__":mys2=S2()printmys2.b1,mys2.b2,mys2.s2

由以上代码可以看出,如要将S1的父类由B2改成B3,则S2的代码几乎没有什么变动(只有第一行类的定义时,将B2改成B3即可)。
要注意的是,在B1和B2的__init__()函数中都用了super(),那么在S2的__init__()函数中也用super(),则只需写一行super()即可,而不用再显式调用所有父类的__init__()函数了。

2. 注意事项

  • 要么采用Python2.2之前的写法,全部显式调用父类的构造器;要么全部用super();不能混用。
  • super、MRO都是针对新式类的;如果是传统类,还是采用上面第一段代码中的写法吧。

3. super()的原理

super()其实做的就是这件事:

defsuper(cls,inst):mro=inst.__class__.mro()returnmro[mro.index(cls)+1]

由以上代码:

  1. inst负责生成MRO的list;
  2. 定位到当前cls在MRO中的位置,然后后移一位,返回此处的类;

MRO就是Method Resolution Order,详见这篇文章The Python 2.3 Method Resolution Order.

请看下面这个钻石继承的例子:

classA(object):def__init__(self):print("In A's __init__()")classB(A):def__init__(self):print("Enter B's __init__()")super(B,self).__init__()print("Leave B's __init__()")classC(A):def__init__(self):print("Enter C's __init__()")super(C,self).__init__()print("Leave C's __init__()")classD(B,C):def__init__(self):print("Enter D's __init__()")super(D,self).__init__()print("Leave D's __init__()")d=D()print(d.__class__.__mro__)

程序的输出如下:

Enter D's __init__() Enter B's __init__() Enter C's __init__() In A's __init__() Leave C's __init__() Leave B's __init__() Leave D's __init__() (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)

从以上程序,可以清楚地看出,在上面这个钻石继承中,最后对于类D来说,其MRO就是 D B C A,故在执行了类B的构造器后,就去执行了类C的构造器,而不是类A的构造器。

关于MRO的一点小总结

  • 基类总是出现在派生类的后面;
  • 如果有多个基类,基类的顺序保持不变。

4. 参考文献

  • Python的内置函数super()与类方法(函数)继承
  • 有关super的问答
  • Things to know about Python super
  • Python’s super() considered super!
  • super on stackoverflow
  • The Python 2.3 Method Resolution Order
http://www.jsqmd.com/news/1203552/

相关文章:

  • Windows Server 2019 KMS激活指南与常见问题解决
  • Windows Server 2019激活机制与slmgr命令详解
  • TensorRT深度学习推理加速实战与优化技巧
  • 一站式直播聚合解决方案:Simple Live如何用Dart技术栈重构你的观看体验
  • 广州夏令营哪家靠谱:军博营地服务周全 - 云溪自乐
  • 安装指南不是文档,是用户信任的第一道契约
  • 眼镜清洗维修门店如何提升附近到店频次?餐宝盈小程序结合GEO服务获客,含零代码SAAS、AI编程、源码定制
  • 如何掌握AI系统全栈技术:从芯片到框架的完整指南
  • Python里os.chdir()不会用?你的代码还在迷路吧
  • 2026年7月最新重庆劳力士官方售后服务网点地址及客服电话一览 - 劳力士官方服务中心
  • GPUStack v0.5:AI模型部署与图生图技术解析
  • Windows Server 2019 Essentials激活指南与常见问题解决
  • WSL2与WSL1核心差异及安装优化指南
  • U盘文件系统格式选择与转换全指南
  • 讲真的2026年大同离婚律师 这5位值得信赖靠谱推荐 - 本地品牌推荐
  • 深圳夏令营性价比排行:军博营地行业魁首 - 秋山寄远
  • 流程科普|无线充 Qi 认证完整办理流程梳理
  • 字模软件增加函数注释 加HEX空格 next Serial
  • Android随笔-ANR
  • Windows 10 Build 10064技术预览版安装与优化指南
  • 百达翡丽中国官方售后服务中心|最新电话和完整维修地址权威信息通知(2026年7月更新) - 百达翡丽官方售后中心
  • 2026年四川地区理赔法律服务诚信品牌深度解析与选择指南 - 品牌鉴赏官2026
  • 广州百达翡丽回收价格查询与靠谱回收平台实测排行(2026年7月最新数据) - 嘉价奢侈品回收平台
  • 评标现场的“数字守护者”:镜像视界视频孪生,如何穿透迷雾,实现精准管控
  • 美度中国官方售后服务中心|服务热线与门店详细地址权威信息公告(2026年7月更新) - 亨得利官方服务中心
  • H5GG终极指南:如何用JavaScript轻松修改iOS游戏内存
  • 泰格豪雅中国官方售后服务中心|服务电话及全部维修地址权威信息公示(2026年7月更新) - 亨得利官方服务中心
  • 2026年近期大型圣诞树批发商专业甄选指南:如何找到供应商 - 品牌鉴赏官2026
  • Java发送HTTP GET请求的5种高效方法
  • 深圳夏令营口碑推荐:军博营地声名远扬 - 云溪自乐