0

0

super在多继承中的调用细节

巴扎黑

巴扎黑

发布时间:2016-11-26 09:56:29

|

1522人浏览过

|

来源于php中文网

原创

注:此处以python 3为运行环境,例子摘自《python cookbook》第8章。 

python中若子类要实现父类的初始化,主要有两种方法,第一种是直接通过父类名,第二种是利用super方法。在单继承时两者没什么区别,但在多继承时就需要注意一些细微的差距了。实例解释才是硬道理! 
1、利用父类名的情况: 

Python代码  

class Base:  

    def __init__(self):  

        print('Base.__init__')  

  

class A(Base):  

    def __init__(self):  

        Base.__init__(self)  

        print('A.__init__')  

  

class B(Base):  

android界面布局详解 中文WORD版
android界面布局详解 中文WORD版

本文档主要讲述的是android界面布局详解;在通过“Hello World!”介绍Android中的布局问题之前,不得不先介绍一下Android中的用户界面,因为布局问题也是用户界面问题之一。在一个Android应用程序中,用户界面通过View和ViewGroup对象构建。Android中有很多种Views和ViewGroups,他们都继承自View类。View对象是Android平台上表示用户界面的基本单元。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过

下载

    def __init__(self):  

        Base.__init__(self)  

        print('B.__init__')  

  

class C(A,B):  

    def __init__(self):  

        A.__init__(self)  

        B.__init__(self)  

        print('C.__init__')  


此时实例化C类会输出如下: 

Python代码  

>>> c = C()  

Base.__init__  

A.__init__  

Base.__init__  

B.__init__  

C.__init__  

>>>  


从中可看出Base类被调用了两次。这想必在很多情况下都不是我们想要的结果,所以此时可考虑用super方法。 

2、利用super的情况: 

Python代码  

class Base:  

    def __init__(self):  

        print('Base.__init__')  

  

class A(Base):  

    def __init__(self):  

        super().__init__()  

        print('A.__init__')  

  

class B(Base):  

    def __init__(self):  

        super().__init__()  

        print('B.__init__')  

  

class C(A,B):  

    def __init__(self):  

        super().__init__() # Only one call to super() here  

        print('C.__init__')  


此时再实例化C类的输出为: 

Python代码  

>>> c = C()  

Base.__init__  

B.__init__  

A.__init__  

C.__init__  

>>>  


可看出Base类是不是只调用了一次啊!但很遗憾的是,这并不是促使我写这篇博客记录的原因,因为如果仔细观察的话,虽说Base类的确如预期只调用了一次,但你有没有发觉是先输出“B.__init__”而后才输出的“A.__init__”?而且为什么这样就使得Base只初始化了一次?想必你也有点懵逼了吧?其实这一切都得“怪罪”于super在多继承时的调用过程。python在实现一个类(不仅是继承)时,会产生一个方法生成解析顺序列表,该列表可通过类属性 __mro__ 查看之,如本例中是这样的: 

Python代码  

>>> C.__mro__  

(,  

)  

>>>  


所以在搜索一个属性或方法时,它就会按照这个列表遍历每个类,直到找到第一个匹配这个属性或方法的类为止。而在继承中使用super时,解释器会每遇到一次super就会在该列表上搜索下一个类,直到不再遇到super或列表遍历完为止,然后再类似递归逐层返回。因此本例中搜索过程为:C中遇到super --> 搜索列表中的下一个类,即A --> A中再次遇到super,搜索B --> B中super再现,搜索Base --> 初始化Base类,递归返回。 
为了更好的解释该过程,现在请注释掉B类的super所在行: 

Python代码  

class B(Base):  

    def __init__(self):  

        #super().__init__()  

        print('B.__init__')  

  

class C(A,B):  

    def __init__(self):  

        super().__init__() # Only one call to super() here  

        print('C.__init__')  


再次实例化C类,输出如下: 

Pythonn代码  

>>> c = C()  

B.__init__  

A.__init__  

C.__init__  


Base类不再产生输出!为什么?因为B中没了super后,就阻断了列表去搜索Base类,所以也就没有初始化Base了!

相关专题

更多
Java 项目构建与依赖管理(Maven / Gradle)
Java 项目构建与依赖管理(Maven / Gradle)

本专题系统讲解 Java 项目构建与依赖管理的完整体系,重点覆盖 Maven 与 Gradle 的核心概念、项目生命周期、依赖冲突解决、多模块项目管理、构建加速与版本发布规范。通过真实项目结构示例,帮助学习者掌握 从零搭建、维护到发布 Java 工程的标准化流程,提升在实际团队开发中的工程能力与协作效率。

4

2026.01.12

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

99

2026.01.09

c++框架学习教程汇总
c++框架学习教程汇总

本专题整合了c++框架学习教程汇总,阅读专题下面的文章了解更多详细内容。

55

2026.01.09

学python好用的网站推荐
学python好用的网站推荐

本专题整合了python学习教程汇总,阅读专题下面的文章了解更多详细内容。

139

2026.01.09

学python网站汇总
学python网站汇总

本专题整合了学python网站汇总,阅读专题下面的文章了解更多详细内容。

12

2026.01.09

python学习网站
python学习网站

本专题整合了python学习相关推荐汇总,阅读专题下面的文章了解更多详细内容。

19

2026.01.09

俄罗斯手机浏览器地址汇总
俄罗斯手机浏览器地址汇总

汇总俄罗斯Yandex手机浏览器官方网址入口,涵盖国际版与俄语版,适配移动端访问,一键直达搜索、地图、新闻等核心服务。

85

2026.01.09

漫蛙稳定版地址大全
漫蛙稳定版地址大全

漫蛙稳定版地址大全汇总最新可用入口,包含漫蛙manwa漫画防走失官网链接,确保用户随时畅读海量正版漫画资源,建议收藏备用,避免因域名变动无法访问。

441

2026.01.09

php学习网站大全
php学习网站大全

精选多个优质PHP入门学习网站,涵盖教程、实战与文档,适合零基础到进阶开发者,助你高效掌握PHP编程。

49

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python进阶视频教程
Python进阶视频教程

共30课时 | 7.9万人学习

DOM探索之基础详解篇
DOM探索之基础详解篇

共20课时 | 3.4万人学习

JavaScript OOP调试技巧视频教程
JavaScript OOP调试技巧视频教程

共5课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号