zoukankan      html  css  js  c++  java
  • 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)
    

      

  • 相关阅读:
    ajax技术
    JSDOM获取子节点的一些方法
    防止a标签跳转的几种方法
    关于childNodes和children
    三种预览图片的方法
    异步加载js文件的方法
    跨域访问的解决方案
    关于在JS中设置标签属性
    Eclipse导入web项目发布项目时报Tomcat version 7.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 and 6 Web错误解决方案
    Maven构建项目报No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK? 问题的解决方案
  • 原文地址:https://www.cnblogs.com/i-honey/p/7831866.html
Copyright © 2011-2022 走看看