【转载】 python之理解super及MRO列表
原文地址: https://www.jianshu.com/p/de7d38c84443
---------------------------------------------------------------------------------------
python之理解super
super(type[, object-or-type])
- type 类。
- object-or-type 类,一般是 self。
1、super
在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过super()来实现,比如:
class Animal(object):
def __init__(self, name):
self.name = name def greet(self):
print('the animal name is %s' % self.name) class Dog(Animal):
def greet(self):
super(Dog, self).greet()
print('wangwang') dog = Dog('huang')
dog.greet()
结果:
the animal name is huang
wangwang
上面Animal是父类,Dog是子类,我们现在Dog类重定义了greet方法,为了能同时实现父类的功能,有利用super调用了父类的greet方法。
super一个常见的用法就是在子类中调用父类的初始化方法了,如:
class Base(object):
def __init__(self, a, b):
self.a = a
self.b = b class Inherit(Base):
def __init__(self, a, b, c):
# super(Inherit, self).__init__(a, b)
super().__init__(a, b) # py3支持的写法
self.c = c
print(self.a)
print(self.b)
print(self.c) test = Inherit('daocoder', 'mudai', 'dao')
结果:
daocoder
mudai
dao
2、深入理解super
上面基本是一般的用法和理解:获取父类,然后调用父类的方法。其实在上面的例子中,super获取的类恰好是父类而已,但在其它情况下就不一样了,super实质上和父类没有关联。
class Base(object):
def __init__(self):
print('enter base')
print('leave base') class A(Base):
def __init__(self):
print('enter A')
super(A, self).__init__()
print('leave A') class B(Base):
def __init__(self):
print('enter B')
super(B, self).__init__()
print('leave B') class C(A, B):
def __init__(self):
print('enter C')
super(C, self).__init__()
print('leave C') c = C()
结果为:
enter C
enter A
enter B
enter base
leave base
leave B
leave A
leave C
Base是父类,A,B继承自Base,C继承自A,B。
3、MRO列表
MRO(method resolution order),事实上,对于你定义的每个类,python都会计算出一个方法解析顺序,它代表了类继承的顺序。我们可以利用下面的方式获得某个类的MRO列表。
同样上面的代码。
print(C.mro())
print(C.__mro__)
print(c.__class__.mro())
结果为:
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>]
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>)
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>]
- 子类永远在父类的前面。
- 如果有多个父类,会根据它们在列表中的顺序去检查。
- 如果对下一个类存在两种不同的合法选择,那么选择第一个父类。
4、super原理
super的工作原理如下:
def super(cls, inst):
mro = inst.__class__.mro()
return mro[mro.index(cls) + 1]
cls代表类,inst代表实例,可以看出上面的代码做了两件事:
- 获取inst的MRO列表。
- 查找cls在MRO的index,并返回它的下一个类,即mro[index + 1]
当你使用super(cls, inst)时,python会在inst的MRO列表上搜索下cls的下一个类。
现在再回答前面的例子:
super(C, self).__init__()
这里的self是C的实例,self.class.mro()的结果是:
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>]
可以看到C的下一个类是A,于是,跳到了A的init,这时会打印enter A,并且执行下面一行代码:
super(A, self).__init__()
上面整个过程还是比较清晰的,关键在于理解super的工作方式,而不是想当然的理解为super调用父类的方法。
作者:道无虚
链接:https://www.jianshu.com/p/de7d38c84443
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【转载】 python之理解super及MRO列表的更多相关文章
- super之mro列表牵引出c3算法
目录 一:super的使用 二:super之mro列表牵引出c3算法 三:mro列表总结使用 一:super的使用 class Person(object): def __init__(self, n ...
- 子类中执行父类的方法(引出super()与mro列表)
1. 我们先想一下在python中如果子类方法中想执行父类的方法,有什么方式?大概有三种: Parent.__init__(self, name) # 通过父类的名字,指定调用父类的方法 super( ...
- [转载]Python: 你不知道的 super
原文出处: geekvi super() 的入门使用 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用 ...
- 认识python中的super函数
需求分析 在类继承中,存在这么一种情况: class Human(object): def Move(self): print("我会走路...") class Man(Human ...
- Python大神必须掌握的技能:多继承、super和MRO算法
本文主要以Python3.x为例讲解Python多继承.super以及MRO算法. 1. Python中的继承 任何面向对象编程语言都会支持继承,Python也不例外.但Python语言却是少数几个支 ...
- Python进阶-继承中的MRO与super
Python进阶-继承中的MRO与super 写在前面 如非特别说明,下文均基于Python3 摘要 本文讲述Python继承关系中如何通过super()调用"父类"方法,supe ...
- Python面向对象中super用法与MRO机制
1. 引言 最近在研究django rest_framework的源码,老是遇到super,搞得一团蒙,多番查看各路大神博客,总算明白了一点,今天做一点总结. 2. 为什么要用super 1)让代码维 ...
- Python的多继承问题-MRO和C3算法
大部分内容转载自C3 线性化算法与 MRO 理解Python中的多继承 Python 中的方法解析顺序(Method Resolution Order, MRO)定义了多继承存在时 Python 解释 ...
- 继承及属性查找+super()和mro()+多态
继承及属性查找+super()和mro()+多态 一. ★继承 1. 什么是继承? 继承就是新建类的一种方式,新建的类我们称为子类或者叫派生类,被继承的类我们称为父类或者基类 子类可以使用父类中的属性 ...
- Python类中super()和__init__()的关系
Python类中super()和__init__()的关系 1.单继承时super()和__init__()实现的功能是类似的 class Base(object): def __init__(sel ...
随机推荐
- helm常用命令
一.helm常用命令 1.查看帮助 helm help 2.创建一个chart包模板 格式: helm create [releasename] 例子: $helm create hello-worl ...
- EF INNER JOIN WHERE ORDER BY
同时使用 join,where,order by. UpdaterDbContext db = new UpdaterDbContext(); // 按 t_server 表的 seq ASC 排序, ...
- 说一下 JSP 的 4 种作用域?
page:代表与一个页面相关的对象和属性. request:代表与客户端发出的一个请求相关的对象和属性.一个请求可能跨越多个页面,涉及多个 Web 组件:需要在页面显示的临时数据可以置于此作用域. s ...
- 哈啰面试:说说Dubbo运行原理?
Dubbo 是一款高性能.轻量级的开源 RPC(远程过程调用)框架,主要用于构建分布式服务和微服务架构.那 Dubbo 又是如何运行的呢?让我们一起来看. 1.核心组件 要说 Dubbo 运行流程就不 ...
- Jenkins构建UI自动化项目,指定本地执行,没弹起浏览显示
1. 原因分析 为什么执行web没有弹出浏览器,Jenkins日志显示正在执行中 jenkins是用windows installer 安装成 windows的服务了,那么启动windows后jenk ...
- 从JDK8升级到JDK17
一.概述 鉴于JDK8已经是老古董,还有性能问题,兼且各个公司已经不再维护1.8的JDK,所以升级公司的核心产品之一的后端到JDK到17是相对要紧的事情. 通过升级到jdk17,具有以下好处: 不要在 ...
- Java面试知识点(二)super 和 this 关键字
this this 是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针. this 的用法在 java 中大体可以分为 3 种: 普通的直接引用 这种就不用讲了,this 相当于是指向 ...
- 第三方App与Termux命令建立IO通道
目录 前言 一.Android 进程间通信(IPC) 二.Netcat 网络瑞士军刀 三.第三方 App 与 Termux 建立 TCP/Socket 通信 四.应用:调用 LSP 语言服务器 参见 ...
- 你要的AI Agent工具都在这里
只有让LLM(大模型)学会使用工具,才能做出一系列实用的AI Agent,才能发挥出LLM真正的实力.本篇,我们让AI Agent使用更多的工具,比如:外部搜索.分析CSV.文生图.执行代码等. 1. ...
- FM20S用户手册--Linux系统启动卡制作及系统固化