Python高级编程之继承问题详解(super与mro)
作者:HMMHMH 发布时间:2023-08-08 18:58:47
本文实例讲述了Python高级编程之继承问题。分享给大家供大家参考,具体如下:
多继承问题
1.单独调用父类:
一个子类同时继承自多个父类,又称菱形继承、钻石继承。
使用父类名.init(self)方式调用父类时:
例:
class Parent(object):
def __init__(self, name):
self.name = name
print('parent的init结束被调用')
class Son1(Parent):
def __init__(self, name, age):
Parent.__init__(self, name)
self.age = age
print('Son1的init结束被调用')
class Son2(Parent):
def __init__(self, name, gender):
Parent.__init__(self, name)
self.gender = gender
print('Son2的init结束被调用')
class Grandson(Son1, Son2):
def __init__(self, name, age, gender):
Son1.__init__(self, name, age) # 单独调用父类的初始化方法
Son2.__init__(self, name, gender)
print('Grandson的init结束被调用')
gs = Grandson('grandson', 12, '男')
执行结果:
可以看出使用父类名.init(self)方式调用父类时,parent父类被调用了两次,此方法对于多继承不太合适。
2.MRO顺序:
上述代码,我们发现由于多继承情况,parent类被的属性被构造了两次,如果在更加复杂的结构下可能更加严重。
为了解决这个问题,Python官方采用了一个算法将复杂结构上所有的类全部都映射到一个线性顺序上,而根据这个顺序就能够保证所有的类都会被构造一次。
这个顺序就是MRO顺序。
MRO顺序采用C3算法广度优先遍历。
使用方法: 类名.mro()或类名.mro()
3.super调用父类:
使用super().init()方式调用父类时:
例:
class Parent(object):
def __init__(self, name, *args, **kwargs): # 为避免多继承报错,使用不定长参数,接受参数
self.name = name
print('parent的init结束被调用')
class Son1(Parent):
def __init__(self, name, age, *args, **kwargs): # 为避免多继承报错,使用不定长参数,接受参数
self.age = age
super().__init__(name, *args, **kwargs) # 为避免多继承报错,使用不定长参数,接受参数
print('Son1的init结束被调用')
class Son2(Parent):
def __init__(self, name, gender, *args, **kwargs): # 为避免多继承报错,使用不定长参数,接受参数
self.gender = gender
super().__init__(name, *args, **kwargs) # 为避免多继承报错,使用不定长参数,接受参数
print('Son2的init结束被调用')
class Grandson(Son1, Son2):
def __init__(self, name, age, gender):
# 多继承时,相对于使用类名.__init__方法,要把每个父类全部写一遍
# 而super只用一句话,执行了全部父类的方法,这也是为何多继承需要全部传参的一个原因
# super(Grandson, self).__init__(name, age, gender)
super().__init__(name, age, gender)
print('Grandson的init结束被调用')
gs = Grandson('grandson', 12, '男')
print(Grandson.__mro__)
运行结果:
parent父类只被调用了一次,super方法会按照MRO顺序调用下一个父类。
总结:
(1)MRO保证了多继承情况 每个类只出现一次
(2)super().init相对于类名.init,在单继承上用法基本无差
(3)但在多继承上有区别,super方法能保证每个父类的方法只会执行一次,而使用类名的方法会导致方法被执行多次
(4)多继承时,使用super方法,对父类的传参数,是由于python中super的算法导致的原因,必须把参数全部传递,否则会报错
(5)单继承时,使用super方法,不能全部传递,只能传父类方法所需的参数,否则会报错
(6)多继承时,相对于使用类名.init方法,要把每个父类全部写一遍, 而使用super方法,只需写一句话便执行了全部父类的方法,这也是为何多继承需要全部传参的一个原因
希望本文所述对大家Python程序设计有所帮助。
来源:https://blog.csdn.net/zsh142537/article/details/82685721


猜你喜欢
- 论坛经常有人会问到用CSS如何美化Select标签,其实但凡你看到很酷的都是用javascript来实现的。昨天试着做了一下,基本实现的初级
- 建立网站时,有很多理由让你遵循Web标准。企业、开发人员和用户都会从兼容标准的做法中获益。这里列举了一些最令人信服的理由,为什么所有网站都应
- 近段时间由于修改一个ASP程序(有SQL注入漏洞),在网上找了很多相关的一些防范办法,都不近人意,所以我将现在网上的一些方法综合改良了一下,
- 以下以 IE 代替 Internet Explorer,以 MF 代替 Mozzila FF1. document.form.item 问题
- 主键表的主键(primary key,主关键字)是表中的一个或多个字段,它的值用于惟一地标识表中的某一条记录。一个表不能有多个主关键字,并且
- 视觉设计是什么,人们怎么认为它的,自己又是怎么对待和理解它,它的核心价值是什么。视觉设计,冒似很艺术,跟艺术相关的职业,给大多数人的印象是做
- 看起来现在经常用到这样的效果来提高用户体验,所以就没事写了一个输入框提示列表的效果使用宽屏的朋友麻烦帮忙测试下,列表的位置有没有错位。代码可
- Oracle 数据库启动Oracle shutdown的时候突然断电,导致使用sql/plus启动时无法连接到数据库,具体描述为: conn
- 如何实现在下拉菜单里输入文字? 用这个代码试试看,应该可以的:<script>function pp(){se.opt
- 如今WEB的安全问题影响着整个安全界,SQL注入,跨站脚本攻击等攻击受到了关注。 网络安全问题日益变的更加重要,国内依然有很多主机受到此类安
- 程序开始:<% Server.ScriptTimeout = &HE10 '&
- 在网络浏览器软件中,可以Internet Explorer (IE)现在是一种标准的软件。可以看到,运行不同版本的Windows操作系统(和
- http://validator.w3.org/#validate_by_upload 在线校验网址点浏览,上次找到自己做的页面
- 原始结构:Column1 Column2----------- ----------1 A1 B2 C2 D2 E3 F查询效果:Colum
- 提到SQL Server 2005证书,很多人可能以为它只是用来在传输数据的时候起到加密作用的,但在深入了解后,你会发现它的用处还有很多。
- Microsoft JET Database Engine 错误 '80040e2
- 这个使用起来很简单,以前需要的时候在网上找的,用了感觉还不错,具体的看演示就明白了。,这个可以保留你文章中的html标记,需要你修改的就是下
- 有很多应用项目, 刚起步的时候用MYSQL数据库基本上能实现各种功能需求,随着应用用户的增多,数据量的增加,MYSQL渐渐地出现不堪重负的情
- 问题:SQL Server 2005中如何利用xml拆分字符串序列?解答:下文中介绍的方法比替换为select union all方法更为见
- 但是Class这个东西,如果用得比较少,充其量只是一个大模块的包装方式. 只有大规模地用它来开发,才能显出它对项目管理的优越性来. 所谓的意