Python 多重继承

合集下载

python 继承方法

python 继承方法

python 继承方法Python 继承方法继承是面向对象编程中的一个重要概念,它允许我们创建一个新类并从现有类中继承属性和方法。

在 Python 中,我们可以通过定义一个类并指定它的父类来实现继承。

本文将介绍 Python 中的继承方法,包括单重继承、多重继承、方法重写等。

一、单重继承单重继承是指一个子类只从一个父类中继承属性和方法。

在 Python 中,我们可以通过在定义子类时将其父类作为参数来实现单重继承。

1. 定义父类首先,我们需要定义一个父类。

父类是包含要被子类所继承的属性和方法的基本模板。

```pythonclass Person:def __init__(self, name, age): = nameself.age = agedef introduce(self):print("My name is {} and I am {} yearsold.".format(, self.age))```上面的代码定义了一个名为 Person 的父类,它包含了两个属性(name 和 age)和一个介绍自己的方法(introduce)。

2. 定义子类接下来,我们需要定义一个子类,并指定它的父类为 Person。

子类可以从其父类中继承所有属性和方法,并且还可以添加自己特有的属性和方法。

```pythonclass Student(Person):def __init__(self, name, age, grade):super().__init__(name, age)self.grade = gradedef introduce(self):print("My name is {} and I am {} years old. I am in grade {}.".format(, self.age, self.grade))```上面的代码定义了一个名为 Student 的子类,它从 Person 类中继承了 name 和 age 属性以及 introduce 方法,并添加了一个自己特有的属性 grade 和一个重写过的 introduce 方法。

python的多重继承的理解

python的多重继承的理解

python的多重继承的理解python的多重继承的理解Python和C++⼀样,⽀持多继承。

概念虽然容易,但是困难的⼯作是如果⼦类调⽤⼀个⾃⾝没有定义的属性,它是按照何种顺序去到⽗类寻找呢,尤其是众多⽗类中有多个都包含该同名属性。

对经典类和新式类来说,属性的查找顺序是不同的。

现在我们分别看⼀下经典类和新式类两种不同的表现:经典类:#! /usr/bin/python# -*- coding:utf-8 -*-class P1():def foo(self):print 'p1-foo'class P2():def foo(self):print 'p2-foo'def bar(self):print 'p2-bar'class C1(P1,P2):passclass C2(P1,P2):def bar(self):print 'C2-bar'class D(C1,C2):passif __name__ =='__main__':d=D()d.foo()d.bar()执⾏的结果:p1-foop2-bar将代码实例,画了⼀个图,⽅便理解:从上⾯经典类的输出结果来看,实例d调⽤foo()时,搜索顺序是 D => C1 => P1,实例d调⽤bar()时,搜索顺序是 D => C1 => P1 => P2总结:经典类的搜索⽅式是按照“从左⾄右,深度优先”的⽅式去查找属性。

d先查找⾃⾝是否有foo⽅法,没有则查找最近的⽗类C1⾥是否有该⽅法,如果没有则继续向上查找,直到在P1中找到该⽅法,查找结束。

新式类:#! /usr/bin/python# -*- coding:utf-8 -*-class P1(object):def foo(self):print 'p1-foo'class P2(object):def foo(self):print 'p2-foo'def bar(self):print 'p2-bar'class C1(P1,P2):passclass C2(P1,P2):def bar(self):print 'C2-bar'class D(C1,C2):passif __name__ =='__main__':print D.__mro__ #只有新式类有__mro__属性,告诉查找顺序是怎样的d=D()d.foo()d.bar()执⾏的结果:(<class '__main__.D'>, <class '__main__.C1'>, <class '__main__.C2'>, <class '__main__.P1'>, <class '__main__.P2'>, <type 'object'>)p1-fooC2-bar从上⾯新式类的输出结果来看,实例d调⽤foo()时,搜索顺序是 D => C1 => C2 => P1实例d调⽤bar()时,搜索顺序是 D => C1 => C2总结:新式类的搜索⽅式是采⽤“⼴度优先”的⽅式去查找属性。

云开发技术应用(Python) 23-2 覆盖方法与多重继承

云开发技术应用(Python) 23-2 覆盖方法与多重继承

23.1.1 覆盖方法
#_*_ coding:utf-8 _*_ class Father: def bad(self): print 'father: smoking, drinking' class Son(Father): def bad(self): Father.bad(self) # 调用父类中的同名方法 print 'son: gambling' # 只添加父类方法中没有的功能 s1 = Son() s1.bad() 执行结果: father: smoking, drinking son: gambling
物,同时也是掠食者,因此它可以同时继承哺乳动物的方法(恒温、胎 生)和掠食动物的方法(捕食猎物)。
23.1.2 多重继承
如果缺乏多重继承的支持,往往会导致同一个功能在多个地方被重写,但多 重继承也存在争议,这主要集中在钻石问题上,下次课程我们会介绍它。 多重继承的语法很简单,类似于定义函数时定义多个参数,多重继承也是在
可以看到,在类Cat中什么都没有定义,但我们可以调用它通过多重继承获 得的方法。 注意,在刚才的代码中出现了__bases__,这是任何类都有的一个隐藏属性, 它是一个元组,包含了当前类的父类,但不包含祖父类。对于没有继承任何父类 的类,它的__bases__是一个空元组。__bases__属于类而并非对象,通过实例来 访问__bases__是非法的,所以在上面的例子中直接使用类名来访问。
在这个例子中,子类调用父类中的同名方法,然后添加继承多个父类。C++和Python支持这样 的特性,而Java、C#等则不允许。 在Python中有两种性质的多重继承,一种是纵向多重继承,即子类
继承父类、父类继承祖父类;另一种是横向多重继承,例如猫是哺乳动

python多重继承新算法C3介绍

python多重继承新算法C3介绍

python多重继承新算法C3介绍mro即 method resolution order (⽅法解释顺序),主要⽤于在多继承时判断属性的路径(来⾃于哪个类)。

在python2.2版本中,算法基本思想是根据每个祖先类的继承结构,编译出⼀张列表,包括搜索到的类,按策略删除重复的。

但是,在维护单调性⽅⾯失败过(顺序保存),所以从2.3版本,采⽤了新算法C3。

为什么采⽤C3算法C3算法最早被提出是⽤于Lisp的,应⽤在Python中是为了解决原来基于深度优先搜索算法不满⾜本地优先级,和单调性的问题。

本地优先级:指声明时⽗类的顺序,⽐如C(A,B),如果访问C类对象属性时,应该根据声明顺序,优先查找A类,然后再查找B类。

单调性:如果在C的解析顺序中,A排在B的前⾯,那么在C的所有⼦类⾥,也必须满⾜这个顺序。

C3算法判断mro要先确定⼀个线性序列,然后查找路径由由序列中类的顺序决定。

所以C3算法就是⽣成⼀个线性序列。

如果继承⾄⼀个基类:复制代码代码如下:class B(A)这时B的mro序列为[B,A]如果继承⾄多个基类复制代码代码如下:class B(A1,A2,A3 ...)这时B的mro序列 mro(B) = [B] + merge(mro(A1), mro(A2), mro(A3) ..., [A1,A2,A3])merge操作就是C3算法的核⼼。

遍历执⾏merge操作的序列,如果⼀个序列的第⼀个元素,是其他序列中的第⼀个元素,或不在其他序列出现,则从所有执⾏merge操作序列中删除这个元素,合并到当前的mro中。

merge操作后的序列,继续执⾏merge操作,直到merge操作的序列为空。

如果merge操作的序列⽆法为空,则说明不合法。

例⼦:复制代码代码如下:class A(O):passclass B(O):passclass C(O):passclass E(A,B):passclass F(B,C):passclass G(E,F):passA、B、C都继承⾄⼀个基类,所以mro序列依次为[A,O]、[B,O]、[C,O]复制代码代码如下:mro(E) = [E] + merge(mro(A), mro(B), [A,B])= [E] + merge([A,O], [B,O], [A,B])执⾏merge操作的序列为[A,O]、[B,O]、[A,B]A是序列[A,O]中的第⼀个元素,在序列[B,O]中不出现,在序列[A,B]中也是第⼀个元素,所以从执⾏merge操作的序列([A,O]、[B,O]、[A,B])中删除A,合并到当前mro,[E]中。

Python类的继承方式

Python类的继承方式

Python类的继承方式Python语言中,类的继承是一种重要的面向对象编程技术。

继承是指在一个已经定义好的类的基础上,创建一个新的类,并对其进行修改和扩展,以便满足新的需求和要求。

Python中的类继承方式包括单继承、多继承、混合继承等,每种方式各有优缺点,程序员可以根据自己的需求和情况进行选择。

1.单继承单继承是指一个类只继承自一个父类。

在Python中,通过在定义类时在括号中指定父类的名称来实现单继承。

例如,下面的代码片段定义了一个名为Square的类,它继承自Rectangle类。

```class Rectangle:def __init__(self, width, height):self.width = widthself.height = heightclass Square(Rectangle):def __init__(self, side):super().__init__(side, side)```其中,Square类继承了Rectangle类的__init__()方法,并使用super()函数调用它。

由于Square类没有自己的__init__()方法,因此它将使用父类的__init__()方法来初始化自己的属性。

另外,Square类还对父类继承来的__init__()方法进行了修改,以便适应自己的需求。

单继承方式的主要优点是简单、易于理解和调试。

由于每个类只继承自一个父类,因此继承关系清晰明了,代码结构清晰易读。

而且,由于单继承方式减少了不同父类之间的冲突,因此程序出现问题的概率也较小。

然而,单继承方式也存在一些限制。

首先,由于一个类只能继承自一个父类,因此在满足多重继承需求时很难适应。

其次,在单继承的情况下,子类无法访问父类之外的属性和方法,这可能会限制子类的能力。

2.多继承多继承是指一个类继承自多个父类。

通过使用逗号分隔符,在定义类时可以指定多个父类的名称。

例如,下面的代码片段定义了一个名为Cube的类,它继承了Square和Rectangle两个类。

Pythonsuper()函数使用及多重继承

Pythonsuper()函数使用及多重继承

Pythonsuper()函数使⽤及多重继承super()函数可以⽤于继承⽗类的⽅法,语法如下:super(type[, object-or-type])虽然super()函数的使⽤⽐较简单,但是需要根据单继承和多继承来分析函数的调⽤关系。

⾸先,当类之间的继承关系为单继承时,函数调⽤关系也⽐较简单,可以参考如下的例⼦:#!/usr/bin/env python3class A(object):def __init__(self):print('class A')class B(A):def __init__(self):super(B, self).__init__()print('class B')b = B()上述代码运⾏结果如下:class Aclass B从结果可以看出,⼦类B在实例化时调⽤了⽗类A的__init__()⽅法。

当进⾏多重继承时,需要考虑MRO的问题。

所谓MRO,即Method Resolution Order,⾃Python2.3以来,MRO采⽤⼴度优先(区别于深度优先)的规则定义。

为了更好的理解这个问题,让我们先来看如下的代码:#!/usr/bin/env python3class A(object):def __init__(self):self.n = 10def minus(self, m):print('minus in class A start')self.n -= mprint('minus in class A end')class B(A):def __init__(self):self.n = 7def minus(self, m):print('minus in class B start')super(B, self).minus(m)self.n -= 2print('minus in class B end')class C(A):def __init__(self):self.n = 12def minus(self, m):print('minus in class C start')super(C, self).minus(m)self.n -= 5print('minus in class C end')class D(B,C):def __init__(self):self.n = 15def minus(self, m):print('minus in class D start')super(D, self).minus(m)self.n -= 2print('minus in class D end')print('The MRO of class D is :')print(D.__mro__)d = D()d.minus(2)print(d.n)代码运⾏结果:The MRO of class D is :(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)minus in class D startminus in class B startminus in class C startminus in class A startminus in class A endminus in class C endminus in class B endminus in class D end4从运⾏结果可以看出,⼦类D的MRO为(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class'__main__.A'>, <class 'object'>),也就是⼦类D的minus函数在调⽤⽗类函数时的调⽤顺序依次为BCA,⽽后续的调试打印信息也正好验证了该顺序。

python中多重继承与super函数用法

python中多重继承与super函数用法

python中多重继承与super函数⽤法python有类似于C++的类继承,例如:class A:def__init__(self):print"init A Class"class B(A):def__init__(self):A()print"init B class"结果:init A Classinit B class在上⾯的继承关系中在初始化类B的时候需要在__init__函数中同时初始化A,在单⼀继承的模式当中,这种⽅式有效切不会引起在错误。

但是如果是多重继承的模式时,⽐如lass A(object):def__init__(self):print"init A Class"class B(A):def__init__(self):A.__init__(self)print"init B class"class C(A):def__init__(self):A.__init__(self)print"init C class"class D(B,C):def__init__(self):B.__init__(self)C.__init__(self)print"init D class"结果:init A Classinit B classinit A Classinit C classinit D class从结果中可以看到classA被初始化了两次,这不是期望的结果,在实际的应⽤中会造成错误,super函数就是为了这种情况⽽存在的,防⽌⽗函数被多次初始化。

例如:class A(object):def __init__(self):print "init A Class"class B(A):def __init__(self):print"init B class"super(B, self).__init__()class C(A):def __init__(self):print"init C class"super(C, self).__init__()class D(B,C):def __init__(self):print "init D class"super(D, self).__init__()class E(A):def __init__(self):print "init E class"super(E, self).__init__()class F(D,E):def __init__(self):print "init F class"super(F, self).__init__()F = F()结果:init F classinit D classinit B classinit C classinit E classinit A Class在⼦类中初始化⽗对象是,利⽤super函数就能够在多重继承的时候只初始化⽗函数⼀次。

python的继承详解

python的继承详解

python的继承详解⽬录1、单继承:⼦类只继承⼀个⽗类2、多继承:⼦类继承多个⽗类3、⼦类重写⽗类的同名属性和⽅法4、⼦类调⽤⽗类同名属性和⽅法5、6、调⽤⽗类⽅法super()总结1、单继承:⼦类只继承⼀个⽗类举例:煎饼果⼦⽼师傅在煎饼果⼦界摸爬滚打⼏⼗年,拥有⼀⾝精湛的煎饼果⼦技术,并总结了⼀套"古法煎饼果⼦配⽅"。

可是⽼师傅年迈已久,在嗝屁之前希望把⾃⼰的配⽅传承下去,于是⽼师傅把配⽅传给他的徒弟⼤猫...虽然⼦类没有定义__init__⽅法初始化属性,也没有定义实例⽅法,但是⽗类有。

所以只要创建⼦类的对象,就默认执⾏了那个继承过来的__init__⽅法⼦类在继承的时候,在定义类时,⼩括号()中为⽗类的名字⽗类的属性、⽅法,会被继承给⼦类2、多继承:⼦类继承多个⽗类⼤猫掌握了师傅的配⽅,可以制作古法煎饼果⼦,但是⼤猫是个爱学习的好孩⼦,他希望学到更多的煎饼果⼦的做法,于是通过百度搜索,找到了⼀家煎饼果⼦培训学校。

多继承可以继承多个⽗类,也继承了所有⽗类的属性和⽅法。

注意:如果多个⽗类中有同名的属性和⽅法,则默认使⽤第⼀个⽗类的属性和⽅法(根据类的魔法属性mro的顺序来查找)多个⽗类中,不重名的属性和⽅法,不会有任何影响。

3、⼦类重写⽗类的同名属性和⽅法⼤猫掌握了师傅的配⽅和学校的配⽅,通过研究,⼤猫在两个配⽅的基础上,创建了⼀种全新的煎饼果⼦配⽅,称之为 "猫⽒煎饼果⼦配⽅"。

⼤猫的新配⽅⼤受欢迎,但是有些顾客希望也能吃到古法配⽅和现代配⽅的煎饼果⼦...(⼦类调⽤⽗类的同名属性和⽅法)4、⼦类调⽤⽗类同名属性和⽅法⽆论何时何地,self都表⽰是⼦类的对象。

在调⽤⽗类⽅法时,通过传递self参数,来控制⽅法和属性的访问修改。

5、⼤猫的煎饼果⼦店⾮常红⽕,终于有⼀天,他成了世界⾸富!!但是他也⽼了,所以他希望把师傅的配⽅和学校的配⽅以及⾃⼰的配⽅继续传承下去...6、调⽤⽗类⽅法super()总结本篇⽂章就到这⾥了,希望能够给你带来帮助,也希望您能够多多关注的更多内容!。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Python 多重继承
继承是面向对象编程的一个重要的方式,因为通过继承,子类就可以扩展父类的功能。

回忆一下4种动物:
∙Dog - 狗狗;
∙Bat - 蝙蝠;
∙Parrot - 鹦鹉;
∙Ostrich - 鸵鸟。

如果按照哺乳动物和鸟类归类,我们可以设计出这样的类的层次:
但是如果按照“能跑”和“能飞”来归类,我们就应该设计出这样的类的层次:
如果要把上面的两种分类都包含进来,我们就得设计更多的层次:
∙哺乳类:能跑的哺乳类,能飞的哺乳类;
∙鸟类:能跑的鸟类,能飞的鸟类。

这么一来,类的层次就复杂了:
如果要再增加“宠物类”和“非宠物类”,这么搞下去,类的数量会呈指数增长,很明显这样设计是不行的。

正确的做法是采用多重继承。

首先,主要的类层次仍按照哺乳类和鸟类设计:
只需要先定义好

对于需要
对于需要
通过多重继承,一个子类就可以同时获得多个父类的所有功能。

MixIn
如果需要“混入”额外的功能,
这种设计通常称之为MixIn。

为了更好地看出继承关系,我们把
MixIn:
MixIn的目的就是给一个类增加多个功能,这样,在设计类的时候,我们优先考虑通过多重继承来组合多个MixIn的功能,而不是设计多层次的复杂的继承关系。

Python自带的很多库也使用了MixIn。

举个例子,Python自带了
造出合适的服务来。

比如,编写一个多进程模式的TCP服务,定义如下:
编写一个多线程模式的UDP服务,定义如下:
如果你打算搞一个更先进的协程模型,可以编写一个
这样一来,我们不需要复杂而庞大的继承链,只要选择组合不同的类的功能,就可以快速构造出所需的子类。

相关文档
最新文档