类的继承
基本概念
定义
格式如下
继承中的访问控制
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)