習題:
1. Shape基類,要求所有子類都必須提供面積的計算,子類有三角形、矩形、圓。
2. 上題圓類的數據可序列化
第一種方法:使用Mixin多繼承組合的方式,混入其它類的屬性和方法
第二種方法:使用裝飾器裝飾類,動態添加屬性和方法
實例:
import math import json import msgpack import pickle class Shape: """防止直接調用父類的area方法""" @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 Rectangle(Shape): """矩形""" def __init__(self,width,height): self.width = width self.height = height @property def area(self): return self.width * self.height def SerializableCircle(cls): """ 1.裝飾器為類動態添加dumps方法""" # print(cls) def dumps(self,t='json'): if t == 'json': return json.dumps(self.__dict__) elif t == 'msgpack': return msgpack.packb(self.__dict__) elif t == 'pickle': with open('dump.txt','wb') as f: return pickle.dump(self.__dict__,f) else: raise NotImplementedError('沒有實現的序列化') cls.dumps = dumps return cls @SerializableCircle # Circle=SerializableCircle(Circle) class Circle(Shape): """圓形""" def __init__(self,radius): self.radius = radius @property def area(self): return (self.radius ** 2) * math.pi # def dumps(self,t='json'): # if t == 'json': # return json.dumps(self.__dict__) # elif t == 'msgpack': # return msgpack.packb(self.__dict__) # elif t == 'pickle': # with open('dump.txt','wb') as f: # return pickle.dump(self.__dict__,f) # else: # raise NotImplementedError('沒有實現的序列化') # sc = Circle(4) # sc.dumps('pickle') class SerializableMixin: """序列化""" def dumps(self,t='json'): if t == 'json': return json.dumps(self.__dict__) elif t == 'msgpack': return msgpack.packb(self.__dict__) elif t == 'pickle': with open('dump.txt','wb') as f: return pickle.dump(self.__dict__,f) else: raise NotImplementedError('沒有實現的序列化') def loads(self,t='json'): pass class SerializableCircleMixin(SerializableMixin,Circle): """ 2.Mixin組合為類動態添加dumps方法""" pass shapes = [Triangle(3,4,5), Rectangle(3,4), Circle(4)] for s in shapes: print('The area of {} = {}'.format(s.__class__.__name__,s.area)) #Mixin scm = SerializableCircleMixin(4) print(scm.area) s = scm.dumps('msgpack') print(s) #裝飾器 sc = Circle(4) s = sc.dumps('json') print(s)