Python 動態添加類方法


 

習題:

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)

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM