解决python super()调用多重继承函数的问题
作者:Real_BB 发布时间:2022-09-28 07:50:44
当类间继承关系很简单时,super()的使用很简单。
class A(object):
def __init__(self):
print('a')
class B(A):
def __init__(self):
super(B, self).__init__()
print('b')
b = B()
输出结果:
a
b
当一个类继承多个类时,问题就复杂起来了,请看下例:
class A(object):
def __init__(self):
print('a')
class B(object):
def __init__(self):
print('b')
class C(A, B):
def __init__(self):
super(C, self).__init__()
print('c')
c = C()
咋一看,情况好像也不复杂,结果输出a, c嘛。没错!但是如果C类想同时调用A与B的__init__()呢?
有童鞋就要说了,我显示调用不就OK了嘛?
class A(object):
def __init__(self):
print('a')
class B(object):
def __init__(self):
print('b')
class C(A, B):
def __init__(self):
A.__init__()
B.__init__()
print('c')
c = C()
效果一样,还不够好。因为没有调用super(),super的一大好处在于,当父类的名字修改时,其继承类不用修改调用方法。
下面给出完美解决方案:
class A(object):
def __init__(self):
super(A, self).__init__()
print('a')
class B(object):
def __init__(self):
super(B, self).__init__()
print('b')
class C(A, B):
def __init__(self):
super(C, self).__init__()
print('c')
print(C.mro())
c = C()
print(C.mro()),在实际中可以去掉,为啥写在这里,后面再说。
输出结果:
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>]
b
a
c
注意:输出结果是b, a, c而非a, b, c。为什么?
这里就要用上面的mro()输出来解释了。MRO全称Method Resolution Order, 就是用来定义继承方法的调用顺序,自Python2.3以来,MRO采用广度优先(区别于深度优先)的规则定义。按广度优先的规则,出来的顺序就是:
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>]
而每次调用super()则是,调用MRO中下一个函数。上面的例子中:super(C, self)则指向MRO中的下一个类(A), 于是调用A的init --> 在A的init中,又调用了super(),于是调用MRO中的下一个函数(B) --> B调用下一个(object), object啥也不干 --> 返回B中,print('b') --> 返回A中,print('a') --> 返回C中,print('c')。
这里再次强调一次,super(type, obj).func()函数调用的是,obj实例在MRO中下一个父类的可调用func(),而不是type的父类中的func()(这个是本文第一个示例给你带来的错觉)。
来源:https://blog.csdn.net/DL_ChenBo/article/details/80602113


猜你喜欢
- 一. torch.cat()函数解析1. 函数说明1.1 官网:torch.cat(),函数定义及参数说明如下图所示:1.2 函数功能函数将
- 开门见山,直接以例子介绍: 代码如下:CREATE TABLE [dbo].[course]( [id] [int] NULL,
- 1.闭包的定义和使用当返回的内部函数使用了外部函数的变量就形成了闭包闭包可以对外部函数的变量进行保存,还可以提高代码的可重用性实现闭包的标准
- rs.open sql,conn:如果sql是delete,update,insert则会返
- 阅读上一篇:垂直栅格与渐进式行距(上) 新问题来也匆匆,去也“冲冲”。距上次发布垂直栅格与渐进式行距(上)发布,已经不知不觉过去了
- 1、mysql 导出文件:SELECT `pe2e_user_to_company`.company_name, `pe2e_user_to
- 本文实例分析了Go语言中的指针运算方法。分享给大家供大家参考。具体分析如下:Go语言的语法上是不支持指针运算的,所有指针都在可控的一个范围内
- “重构”的春风吹遍大江南北,互联网一时间风声鹤唳,“div+CSS”俨然已成为一种“时尚”,难以尽数的网站都不约而同地开始了自己的“重构”。
- // NewTimer creates a new Timer that will send// the current time on i
- 本文实例讲述了python获取各操作系统硬件信息的方法。分享给大家供大家参考。具体如下:1. windows使用WMI:(WMI官网地址:h
- 前言在Oracle 和SQL Server等数据库中只有一种存储引擎,所有数据存储管理机制都是一样的。而MySql数据库提供了多种存储引擎。
- 很多时候,用户可能会因为承受不了某一产品中的细节设计而放弃使用该产品,这无疑是让设计人员感很沮丧的事情,因为除去这个细节的问题外,这个产品可
- 如下所示:3σ 原则(u-3*σ ,u+3*σ )离差标准化(x-min)/(max-min)标准差标准化(x-u)/σ小数定标标准化x/1
- 事务处理在各种管理系统中都有着广泛的应用,比如人员管理系统,很多同步数据库操作大都需要用到事务处理。比如说,在人员管理系统中,你删除一个人员
- 如何显示存储在BLOB字段中的图像?showimges.asp' 在浏览器上单独显示图像 <%@ 
- 基础知识实际上,“运算符重载”只是意味着在类方法中拦截内置的操作……当类的实例出现在内置操作中,Python自动调用你的方法,并且你的方法的
- 1.os.system函数wget 是一个下载软件的程序,如果已经下载好该软件,可以用py调用该软件。假如该软件目录在d:\tools\wg
- 本文实例讲述了Python面向对象之多态原理与用法。分享给大家供大家参考,具体如下:目标多态面向对象三大特性封装 根据 职责 将 属性 和
- 乍一看到列表推导式你可能会感到疑惑。它们是一种创建和使用列表的简洁方式。理解列表推导式是有用的,因为你可能在其他人的代码里看到列表推导式。下
- Python是面向对象(OOP)的语言, 而且在OOP这条路上比Java走得更彻底, 因为在Python里, 一切皆对象, 包括int, f