• 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)
    

      

  • 相关阅读:
    JS防Yahoo的选项卡导航特效
    纯CSS制作简洁带提示的导航
    绿色简单的CSS下拉菜单
    JS+CSS防FLASH效果竖向可折叠的滑动菜单
    鼠标划过快速展开的JS下拉菜单
    ASP.NET页面生命周期(转载)
    JS Eval函数作用(转载)
    Html十个不常用的标签(转载)
    CSS定位学习
    FireBug调试器相关(转载)
  • 原文地址:https://www.cnblogs.com/i-honey/p/7831866.html
Copyright © 2020-2023  润新知