zoukankan      html  css  js  c++  java
  • Pyhon进阶9---类的继承

    类的继承

    基本概念

    定义

    格式如下

    继承中的访问控制

    class Animal:
        __CNOUT = 0
        HEIGHT = 0
    
        def __init__(self,age,weight,height):
            self.__CNOUT =self.__CNOUT + 1
            self.age = age
            self.__weight = weight
            self.HEIGHT = height
    
        def eat(self):
            print('{} eat'.format(self.__class__.__name__))
    
        def __getweight(self):
            print(self.__weight)
    
        @classmethod
        def showcount1(cls):
            print(cls.__CNOUT)
    
        @classmethod
        def __showcount2(cls):
            print(cls.__CNOUT)
    
    class Cat(Animal):
        NAME = 'CAT'
    
    c = Cat(3,5,15)
    c.eat()
    c.showcount1()#注意此处的cls.__COUNT仍为0
    
    print(c.NAME)
    print(c.__dict__)#{'_Animal__CNOUT': 1, 'age': 3, '_Animal__weight': 5, 'HEIGHT': 15}
    print(Cat.__dict__)#{'__module__': '__main__', 'NAME': 'CAT', '__doc__': None}
    print(Animal.__dict__)#{'__module__': '__main__', '_Animal__CNOUT': 0, 'HEIGHT': 0,...}

     

    方法的重写、覆盖override

    class Animal:
        def shout(self):
            print('Animal shout')
    
    class Cat(Animal):
        #覆盖父类的方法
        def shout(self):
            print('miao')
        #覆盖自身的方法,显示调用了父类的方法
        def shout(self):
            print(super(Cat, self))
            super().shout()
    
    a = Animal()
    a.shout()
    c =Cat()
    c.shout()
    
    #输出结果:
    # Animal shout
    # <super: <class 'Cat'>, <Cat object>>
    # Animal shout

     

    class Animal:
        @classmethod
        def class_method(cls):
            print('class_method_animal')
    
        @staticmethod
        def static_method():
            print('static_method_animal')
    
    class Cat(Animal):
        @classmethod
        def class_method(cls):
            print('class_method_cat')
    
        @staticmethod
        def static_method():
            print('static_method_cat')
    
    c = Cat()
    c.class_method()
    c.static_method()
    #输出结果:
    # class_method_cat
    # static_method_cat

    继承中的初始化

    示例1

    class A:
        def __init__(self):
            self.a1 = 'a1'
            self.__a2 = 's2'
            print('A init')
    
    class B(A):
        pass
    b = B()
    print(b.__dict__)       #{'a1': 'a1', '_A__a2': 's2'}

    示例2

    class A:
        def __init__(self):
            self.a1 = 'a1'
            self.__a2 = 's2'
            print('A init')
    
    class B(A):
        def __init__(self):
            self.b1 = 'b1'
            print('B init')
    b = B()
    print(b.__dict__)    #{'b1': 'b1'}

    class A:
        def __init__(self):
            self.a1 = 'a1'
            self.__a2 = 's2'
            print('A init')
    
    class B(A):
        def __init__(self):
            # A.__init__(self)
            # super(B,self).__init__()
            super().__init__()
            self.b1 = 'b1'
            print('B init')
    b = B()
    print(b.__dict__)   #{'a1': 'a1', '_A__a2': 's2', 'b1': 'b1'}

    如何正确初始化

     

    class Animal:
        def __init__(self,age):
            print('Animal init')
            self.age =age
    
        def show(self):
            print(self.age)
    
    class Cat(Animal):
        def __init__(self,age,weight):
            super().__init__(age)#c.show()结果为11
            print('Cat init')
            self.age = age + 1
            self.weight = weight
            # super().__init__(age)#c.show()结果为10
    c = Cat(10,5)
    c.show()   
    # c.__dict__ {'age': 11, 'weight': 5}

    class Animal:
        def __init__(self,age):
            print('Animal init')
            self.__age =age
    
        def show(self):
            print(self.__age)
    
    class Cat(Animal):
        def __init__(self,age,weight):
            super().__init__(age)
            print('Cat init')
            self.__age = age + 1
            self.__weight = weight
    c = Cat(10,5)
    c.show()
    print(c.__dict__)#{'_Animal__age': 10, '_Cat__age': 11, '_Cat__weight': 5}

     

    Python不同版本的类

    多继承

     

    多继承弊端

    Python多继承实现

    class ClassName(基类列表):
        类体

    多继承的缺点

    Mixin

    class Printable:
        def _print(self):
            print(self.content)
    
    class Document:#假设为第三方库,不允许修改
        def __init__(self,content):
            self.content = content
    
    class Word(Document):pass#假设为第三方库,不允许修改
    class Pdf(Document):pass#假设为第三方库,不允许修改
    
    class PrintableWord(Printable,Word):pass
    print(PrintableWord.__dict__)
    print(PrintableWord.mro())
    pw = PrintableWord('test string')
    pw._print()

      

    def printable(cls):
        def _print(self):
            print(self.content,'装饰器')
        cls.print = _print
        return cls
    
    class Document:#假设为第三方库,不允许修改
        def __init__(self,content):
            self.content = content
    
    class Word(Document):pass#假设为第三方库,不允许修改
    class Pdf(Document):pass#假设为第三方库,不允许修改
    
    @printable
    class PrintableWord(Word):pass
    
    print(PrintableWord.__dict__)#{'__module__': '__main__', '__doc__': None, 'print': <function printable.<locals>._print at 0x0000000002961730>}
    PrintableWord('test').print()#test 装饰器

    4.Mixin

    #Mixin示例1
    class PrintableMixin:
        def print(self):
            print(self.content,'Mixin')
    
    
    class Document:
        def __init__(self,content):
            self.content = content
    
    class Word(Document):pass
    class Pdf(Document):pass
    
    class PrintableWord(PrintableMixin,Word):pass
    print(PrintableWord.__dict__)
    print(PrintableWord.mro())
    
    pw = PrintableWord('test
    string')
    pw.print()

     

    #Mixin示例2
    class PrintableMixin:
        def print(self):
            print(self.content,'Mixin')
    
    
    class Document:
        def __init__(self,content):
            self.content = content
    
    class Word(Document):pass
    class Pdf(Document):pass
    
    class SuperPrintableMixin(PrintableMixin):
        def print(self):
            print('~'*20)
            super().print() #通过继承复用
            print('~'*20)
    
    class SuperPrintablePdf(SuperPrintableMixin,Pdf):pass
    print(SuperPrintablePdf.__dict__)
    print(SuperPrintablePdf.mro())
    
    spp = SuperPrintablePdf('super print pdf')
    spp.print()

    Mixin类

     练习

    #1.Shape基类,要求所有子类都必须提供面积的计算,子类有三角形、矩形、圆
    import  math
    
    class Shape:
        @property
        def area(self):
            raise NotImplementedError('基类未实现')
    
    class Triangle(Shape):
        def __init__(self,a,b,c):
            self.a = a
            self.b = b
            self.c = c
    
        @property
        def area(self):
            p  = (self.a+self.b+self.c)/2
            return math.sqrt(p*(p-self.a)*(p-self.b)*(p-self.c))
    
    class Circle(Shape):
        def __init__(self,radius):
            self.radius = radius
    
        @property
        def area(self):
            return math.pi*self.radius**2
    
    class Rectangle(Shape):
        def __init__(self,width,height):
            self.width = width
            self.height = height
    
        @property
        def area(self):
            return self.width*self.height
    
    # shapes = [Triangle(3,4,5),Rectangle(3,4),Circle(4)]
    # for s in shapes:
    #     print('The area of {} = {}'.format(s.__class__.__name__,s.area))
    
    #2.圆类的数据可序列化
    import json
    import msgpack
    
    def mydump(cls):
        def _dumps(self, t='json'):
            if t == 'json':
                return json.dumps(self.__dict__)
            elif t == 'msgpack':
                return msgpack.packb(self.__dict__)
            else:
                raise NotImplementedError('没有实现的序列化')
        cls.dumps = _dumps
        return cls
    
    #使用Mixin类
    # class SerializableMixin:
    #     def dumps(self,t='json'):
    #         if t == 'json':
    #             return json.dumps(self.__dict__)
    #         elif t == 'msgpack':
    #             return msgpack.packb(self.__dict__)
    #         else:
    #             raise NotImplementedError('没有实现的序列化')
    #
    #使用装饰器
    @mydump
    class SerializableCircleMixin(Circle):pass
    
    scm  = SerializableCircleMixin(1)
    print(scm.area)#3.141592653589793
    print(scm.__dict__)#{'radius': 1}
    print(scm.dumps('json'))#{"radius": 1}

     作业

     

    #单链表
    class SingleNode:
        #代表一个节点
        def __init__(self,val,next=None):
            self.val = val
            self.next = None
    
    class LinkedList:
        #容器类,某种方式存储一个个节点
        def __init__(self):
            self.head = None
            self.tail = None
    
        def append(self,val):
            node = SingleNode(val)
            if self.head is None:# 0
                self.head = node
                self.tail = node
            self.tail.next = node
            self.tail = node
    
        def iternodes(self):
            while self.head:
                yield self.head.val
                self.head = self.head.next
     1 #实现双向链表
     2 class SingleNode:
     3     #代表一个节点
     4     def __init__(self,val,next=None,prev=None):
     5         self.val = val
     6         self.next = next
     7         self.prev = prev
     8 
     9     def __repr__(self):
    10         return str(self.val)
    11 
    12 class LinkedList:
    13     #容器类,某种方式存储一个个节点
    14     def __init__(self):
    15         self.head = None
    16         self.tail = None
    17 
    18     def append(self,val):
    19         node = SingleNode(val)
    20         if self.head is None:# 0
    21             self.head = node
    22         else:
    23             self.tail.next = node
    24             node.prev = self.tail
    25         self.tail = node
    26 
    27     def pop(self):
    28         if self.tail is None:#0
    29             raise NotImplementedError('Empty')
    30         tail = self.tail
    31         prev= self.tail.prev
    32         if prev is None:#1个节点
    33             self.head = None
    34             self.tail = None
    35         else:#>1
    36             self.tail = prev
    37             prev.next = None
    38         return tail.val
    39 
    40 
    41     def insert(self,index,val):#1,7
    42         if index < 0:
    43             raise Exception('Error')
    44         cur = None
    45         for i,current in enumerate(self.iternodes()):
    46             if i == index:
    47                 cur = current
    48                 break
    49 
    50         if cur is None:#说明索引越界或空链表,直接末尾追加
    51             self.append(val)
    52             return
    53 
    54         node = SingleNode(val)
    55         prev = cur.prev
    56         if prev is None:#1个节点,头部插入
    57             self.head = node
    58             node.next = cur
    59             cur.prev = node
    60         else:#>=2
    61             node.next = cur
    62             prev.next = node
    63             cur.prev = node
    64             node.prev = prev
    65 
    66     def iternodes(self,reversed = False):
    67         current = self.head
    68         while current:
    69             yield current
    70             current = current.next
    71 
    72 a = SingleNode(1)
    73 b = SingleNode(2)
    74 c = SingleNode(3)
    75 d = SingleNode(4)
    76 e = SingleNode(5)
    77 f = SingleNode(6)
    78 ll = LinkedList()
    79 ll.append(a)
    80 ll.append(b)
    81 ll.append(c)
    82 ll.append(d)
    83 ll.append(e)
    84 ll.append(f)
    85 # ll.insert(1,0)
    86 # ll.insert(0,0)
    87 ll.insert(10,100)
    88 print('pop元素:',ll.pop())
    89 print('pop元素:',ll.pop())
    90 print('pop元素:',ll.pop())
    91 ll.insert(0,10)
    92 
    93 for node in ll.iternodes():
    94     print(node)
    做一枚奔跑的老少年!
  • 相关阅读:
    Atitit sql计划任务与查询优化器统计信息模块
    Atitit  数据库的事件机制触发器与定时任务attilax总结
    Atitit 图像处理知识点体系知识图谱 路线图attilax总结 v4 qcb.xlsx
    Atitit 图像处理 深刻理解梯度原理计算.v1 qc8
    Atiti 数据库系统原理 与数据库方面的书籍 attilax总结 v3 .docx
    Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析
    Atitit View事件分发机制
    Atitit 基于sql编程语言的oo面向对象大规模应用解决方案attilax总结
    Atitti 存储引擎支持的国内点与特性attilax总结
    Atitit 深入理解软件的本质 attilax总结 软件三原则"三次原则"是DRY原则和YAGNI原则的折
  • 原文地址:https://www.cnblogs.com/xiaoshayu520ly/p/10727958.html
Copyright © 2011-2022 走看看