python继承多个类,python 多继承

  python继承多个类,python 多继承

  文章目录Python多继承多继承Python多继承实现多继承缺点Mixin * Idea 1 * * Idea 2 * * Idea 3 * * Idea 4 * Mixin类

  Python中类的多重继承

  在Python2.2之前,类没有共同的祖先。之后引入了object类,它是所有类的共同祖先。Python2为了兼容,分为经典类(老类)和新类。Python3充满了新的类。新类是从object继承的,新类可以使用super。

  #下面的代码运行在Python2.x #经典类(旧类)class A:pass#新类class b(object):pass sprint(dir(A))Print(dir(b))Print(A . _ _ bases _ _)Print(b . _ _ bases _ _)#经典类A Print(A . _ _ class _ _)Print(type(A))# type instance #新类b=b()Print(b . _ _ class _ _)Print(type(b))多继承OCP原理:多“继承”少修改

  继承的目的:增强基类,在子类上实现多态性多态:在面向对象中,父类和子类通过继承联系在一起。如果可以采用一套方法,就可以实现不同的表达,也就是多态。一个类继承自多个类就是多继承,它将具有多个类的特征。

  多继承劣势多继承很好的模拟了世界,因为事物很少是单继承的,但是抛弃简单必然导致复杂和冲突。多重继承的实现会导致代码设计的复杂性,所以一些高级编程语言放弃了类的多重继承。c支持多重继承;Java抛弃了多重继承。在Java中,一个类可以实现多个接口,一个接口可以继承多个接口。Java的接口是纯的,只是方法的声明。接班人必须实现这些方法,有了这些能力,他就可以做任何事情。多重继承可能会导致二义性。实现多继承语言,要解决歧义,优先考虑深度或广度。Python多重继承实现类类名:类体

  左图为多重继承(钻石继承),右图为单一继承。

  继承带来了路径选择的问题。应该继承哪个父类?

  使用Python MRO(method resolution order method to resolve order)解决基类搜索顺序问题。

  历史原因,MRO有三种搜索算法:

  经典算法:根据定义,从左到右,深度优先策略。在2.2版本之前,左图的MRO是MyClass,D,B,A,C,A新式类算法:是经典算法的升级,深度第一,只保留最后一个给重复的。2.2版左图的MRO是MyClass,D,B,C,A,ObjectC3算法:创建类时,计算mro的有序列表。2.3之后,Python3唯一支持的算法。左图的MRO是我的类,d,b,c,a,object的列表。C3算法在解决多重继承的二义性经典算法中存在很大问题。如果C中有一个方法覆盖了A,就不会被访问,因为A是先被访问的(深度优先)。

  新的类算法仍然采用深度优先,解决了重复的问题,但是和经典算法一样,没有解决继承的单调性。

  C3算法解决了继承的单调性,防止了前一版本产生二义性代码。线性化得到MRO的本质,确定阶数。

  单调性:假设有A,B,C三个类,C的mro为[C,A,B],那么A,B在C子类的mro中的顺序是单调的。类多的时候继承有很多弊端。在继承复杂的情况下,继承路径太多了,很难说是什么样的继承路径。Python的语法允许多重继承,但是Python的代码是被解释和执行的。只有当它被执行时,才发现错误。协同开发,如果引入多重继承,代码可能会不可控。无论编程语言是否支持多重继承,都应该避免多重继承。Python的面向对象,我们看到的太灵活了,太开放了,所以团队要守规矩。

  Mixin类有以下继承关系

  文档类是所有其他文档类的抽象基类;Word和Pdf类是Document的子类。

  要求:为文档子类提供打印功能。

  1在文档中提供打印方法的思路

  假设你已经有了以下三个类class Document: def __init__(self,Content):self . Content=Content def print(self):# abstract method raise notified error()class word(Document):pass # other functions省略class Pdf(Document):pass # other functions省略了基类提供的方法,具体可能实现不了,因为可能不适合打印子类,子类中需要覆盖重写。在基类中定义但未实现的方法称为“抽象方法”。在Python中,如果采用这样定义的抽象方法,子类就可以不实现,直到子类使用这个方法并报错。打印是——打印功能的一项功能,并不是文档的所有子类都需要。所以从这个角度来说,上面的基类文档的设计是有问题的。

  2思路:给需要打印的子类增加打印功能。

  如果直接添加到现有的子类Word或Pdf中,虽然可以,但是违背了OCP原理,所以可以继承,可以添加打印功能。于是就有了下面这张图。

  类文档:#第三方库,不允许修改def _ _ init _ _ (self,content):self . content=content class word(Document):pass #第三方库,不允许修改类Pdf(Document): pass #第三方库。不允许修改#单继承类printable word(word):def print(self):print(self。内容,自我。_ _ class _ _ _ _ name _ _)打印(可打印字。_ _ dict _ _)print(printable word . mro())pw=printable word(

  看起来不错。如果需要提供其他能力,怎么继承?

  比如网络中使用的类,也要有序列化的能力,序列化要在类上实现。

  序列化也可以分为使用pickle、json、messagepack等。

  这个时候我发现,为了增加一种能力,我不得不增加一种传承。可能是类太多,传承的方式不太好。

  功能太多了。A类需要一些功能,B类需要其他功能。它们需要多种功能的自由组合,继承和实现都很繁琐。

  3.创意装饰师。用装饰器增强一个类,给类附加函数,如果类需要就装饰它。类文档:#第三方库,不允许修改def _ _ init _ _ (self,content):self . content=content class word(Document):pass #第三方库,不允许修改类Pdf(Document): pass #第三方库。不允许修改# class decorator,动态地给类添加打印功能。def打印表格(CLS):def _ print(self):print(self . content,-Decorator )cls . print=_ print return cls @ print table class可打印word(word):pass @ print table class可打印pdf (pdf): passsprint(可打印word。_ _ dict _ _)Print(printable word . mro())pw=printable word(我是word打印机)pw.print()pf=PrintablePdf(我是Pdf打印机)pf.print()

  优点:简单方便,需要的地方可以动态添加,装饰器可以直接使用。您可以灵活地向类中添加函数。4 Idea使用Mixin类增强类文档:#第三方库。不允许修改def _ _ init _ _ (self,content):self . content=content class word(document):pass #第三方库。Class Pdf(Document): pass #第三方库和class printable mixin:def print(self):print(self。内容,-mixin类增强)类可打印字(printable mixin,Word): pass类可打印pdf (printable mix,pdf): passsprint(可打印字。_ _ dict _ _)print(printable word . mro())pw=printable word(我是word打印机)pf.print()pf=PrintablePdf(我是Pdf打印机)pf

  Mixin是其他类的混合体,也带来了类的属性和方法。Mixin类和decorator的效果一样,没有什么特别的。但是Mixin是一个类,所以可以继承。

  如果前面的代码完成后再次开发,需要再次增强原来的打印功能,可以重新编写一个增强的打印功能。如果您需要再次使用此增强打印功能,您可以继承增强打印功能。

  类文档:#第三方库,不允许修改def _ _ init _ _ (self,content):self . content=content class word(Document):pass #第三方库,不允许修改类Pdf(Document): pass #第三方库。Class printable mixin:def print(self):print(self . content,-mixin Class enhancement )Class printable Word(printable mixin,Word):pass Class printable Pdf(printable mixin,Pdf): passprint (printable word。_ _ dict _ _)print(Printable word . mro())pw=Printable word(我是word打印机)pw.print()pf=PrintablePdf(我是Pdf打印机)pf . print()# Class super Printable Mix(Printable Mix):def print(self):print(- * 10,预打印增强)super()。print() print(- *10,打印后增强)#使用新的增强要素类super printable PDF(super printable mixin,PDF):pass print()print(super printable PDF。_ _ dict _ _)print(super printable Pdf . mro())spp=super printable Pdf(我是超级Pdf)spp.print

  Mixin类Mixin本质上是一个多继承实现。

  Mixin体现了一种组合的设计模式。

  在面向对象设计中,一个复杂的类往往需要很多功能,而这些功能又是由不同的类提供的,这就需要将很多类组合在一起。

  从设计模式来看,组合多,继承少。

  Mixin类的使用原则

  Mixin类中不应有显式__init__初始化方法。Mixin类通常不能独立工作,因为它是要混合到其他类中的功能的一部分。Mixin类的祖先类也应该是Mixin类。使用时Mixin类通常在继承列表的第一个位置例如:class printable word(可打印mixin,word):传递mixin类和decorator。两种方法都可以,看个人喜好。如果还需要继承,就要用Mixin类了。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: