python 面向对象十一 super函数

super函数用来解决钻石继承。

一、python的继承以及调用父类成员

父类:

class Base(object):

    def __init__(self):
        print("base init.")

普通方法调用父类:

class Leaf(Base):

    def __init__(self):
        Base.__init__(self)
        print("Leaf init.")

super方法调用父类:

class Leaf(Base):

    def __init__(self):
        super(Leaf, self).__init__()
        print("Leaf init.")

二、钻石继承

使用普通方法调用父类,base类会初始化2次。用super解决这个问题。

class Base(object):

    def __init__(self):
        print("Base init")

class Medium1(Base):

    def __init__(self):
        super(Medium1, self).__init__()
        print("Medium1 init")

class Medium2(Base):

    def __init__(self):
        super(Medium2, self).__init__()
        print("Medium2 init")

class Leaf(Medium1, Medium2):

    def __init__(self):
        super(Leaf, self).__init__()
        print("Leaf init")

leaf = Leaf()

三、super工作原理

要理解super的原理,就要先了解mro。mro是method resolution order的缩写,表示了类继承体系中的成员解析顺序。在python中,每个类都有一个mro的类方法。我们来看一下钻石继承中,Leaf类的mro是什么样子的:

print(Leaf.mro())
[<class ‘__main__.Leaf‘>, <class ‘__main__.Medium1‘>, <class ‘__main__.Medium2‘>, <class ‘__main__.Base‘>, <class ‘object‘>]

可以看到mro方法返回的是一个祖先类的列表。Leaf的每个祖先都在其中出现一次,这也是super在父类中查找成员的顺序。

通过mro,python巧妙地将多继承的图结构,转变为list的顺序结构。super在继承体系中向上的查找过程,变成了在mro中向右的线性查找过程,任何类都只会被处理一次。

通过这个方法,python解决了多继承中的2大难题:

1. 查找顺序问题。从Leaf的mro顺序可以看出,如果Leaf类通过super来访问父类成员,那么Medium1的成员会在Medium2之前被首先访问到。如果Medium1和Medium2都没有找到,最后再到Base中查找。

2. 钻石继承的多次初始化问题。在mro的list中,Base类只出现了一次。事实上任何类都只会在mro list中出现一次。这就确保了super向上调用的过程中,任何祖先类的方法都只会被执行一次。

四、super的使用方法

用法一、super(type, obj)

当我们在Leaf的__init__中写这样的super时:

class Medium1(Base):

    def __init__(self):
        super(Medium1, self).__init__()
        print("Medium1 init")

super(Leaf, self).__init__()的意思是说:

  1. 获取self所属类的mro, 也就是[Leaf, Medium1, Medium2, Base]
  2. 从mro中Leaf右边的一个类开始,依次寻找__init__函数。这里是从Medium1开始寻找
  3. 一旦找到,就把找到的__init__函数绑定到self对象,并返回

从这个执行流程可以看到,如果我们不想调用Medium1的__init__,而想要调用Medium2的__init__,那么super应该写成:super(Medium1, self)__init__()

用法二、super(type, type2)

class Leaf(Medium1, Medium2):

    def __new__(cls):
        obj = super(Leaf, cls).__new__(cls)
        print("Leaf new")
        return obj

super(Leaf, cls).__new__(cls)的意思是说:

  1. 获取cls这个类的mro,这里也是[Leaf, Medium1, Medium2, Base]
  2. 从mro中Leaf右边的一个类开始,依次寻找__new__函数
  3. 一旦找到,就返回“ 非绑定 ”的__new__函数

由于返回的是非绑定的函数对象,因此调用时不能省略函数的第一个参数。这也是这里调用__new__时,需要传入参数cls的原因,同样的,如果我们想从某个mro的某个位置开始查找,只需要修改super的第一个参数就行。

时间: 2024-09-30 12:18:13

python 面向对象十一 super函数的相关文章

六. python面向对象(内置函数)

一. 内置函数 [email protected] property 内置装饰器函数 只在面向对象中使用 函数的作用是在新式类中返回属性值. from math import pi print(pi) class Circle: def __init__(self,r): self.r=r def per(self): # 周长 return 2*pi*self.r def aer(self): # 面积 return self.r**2*pi aa=Circle(3) print(aa.per

python面向对象super函数

python面向对象super函数 待办 python面向对象可以多继承,同时集成的两个类继承自同一个父类的时候初始化问题,提前定义初始顺序,如果有相同的就按顺序初始化,不要把super理解成父类 https://blog.csdn.net/robinjwong/article/details/48369615 原文地址:https://www.cnblogs.com/lishikai/p/12382320.html

由Python的super()函数想到的

python-super *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* BLOCKS =============================================================================*/ p, blockquote, ul, ol, dl, table, pre { margin: 15px

【7】python核心编程 第十一章-函数和函数式编程

1.*函数(与方法)装饰器 装饰器背后的主要动机源自python 面向对象编程.装饰器是在函数调用之上的修饰.这些修饰 仅是当声明一个函数或者方法的时候,才会应用的额外调用. 装饰器的语法以@开头,接着是装饰器函数的名字和可选的参数.紧跟着装饰器声明的是被修饰 的函数,和装饰函数的可选参数.装饰器看起来会是这样: @decorator(dec_opt_args) def func2Bdecorated(func_opt_args): : 那么什么是装饰器? 现在我们知道装饰器实际就是函数.我们也

python基础----多态与多态性、super函数用法、继承原理

目录: 一.多态与多态性 二.super函数用法 三.继承原理 一.多态与多态性                                                                        ㈠多态: 多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承) 1. 序列类型有多种形态:字符串,列表,元组. 2. 动物有多种形态:人,狗,猪 1 import abc 2 class Animal(metaclass=abc.ABCMeta):

关于Python中的类普通继承与super函数继承

关于Python中的类普通继承与super函数继承 1.super只能用于新式类 2.多重继承super可以保公共父类仅被执行一次 一.首先看下普通继承的写法 二.再看看super继承的写法 参考链接:http://blog.csdn.net/lqhbupt/article/details/19631991

Python super() 函数

Python super() 函数  Python 内置函数 描述 super() 函数是用于调用父类(超类)的一个方法. super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO).重复调用(钻石继承)等种种问题. MRO 就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表. 语法 以下是 super() 方法的语法: super(type[, object-or-type]) 参数 type -- 类. obj

python之类中的super函数

作用 实现代码重用 思考:super真的只是调用父类么? super函数是按照mro算法去调用的,不bb上代码: class A: def __init__(self): print('A') class B(A): def __init__(self): print('B') super().__init__() class C(A): def __init__(self): print('C') super().__init__() class D(B, C): def __init__(s

python面向对象---用函数实现面向对象原理

类的定义:一个抽象的概念,保存一些共有的属性和特征 #对象:对象代表具体事物的特征功能,是类的实例 #面向对象程序设计 通过函数实现面向对象设计 def dog(name,type,gender): def jiao(dog1): print("你看[%s]狗再叫" % dog1["name"]) #函数的局部作用域 def sleeping(dog1): print("你看[%s]的类别" %dog1["type"]) #初