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)

  

时间: 2024-10-06 13:42:53

Python 动态添加类方法的相关文章

runtime 方法替换 和 动态添加类方法 结合使用

原文地址:runtime 方法替换 和 动态添加类方法 结合使用 前言:方法替换,可以替换任意外部类的方法,而动态添加方法只能实现在被添加类创建的对象里,但是将方法替换和动态添加方法结合使用,可以实现,对任意外部类动态添加需要的方法. 缺陷:1.含参数的方法难以处理,参数值需要根据实际业务逻辑而定.2.无法实现动态添加实例方法. Create Person.h and Person.m Person.h: 12345 #import <Foundation/Foundation.h> @int

python动态添加属性

class A: def __init__(self, info ={}): self.info = info def __getattr__(self, item): return self.info[item] a =A() a.age = 123 print(a.age) a.name = 123 print(a.name) a.xis = 123 print(a.xis) print(a.__dict__) 原文地址:https://www.cnblogs.com/7134g/p/115

python类对象动态添加属性和方法

class Person(): #创建一个类 def __init__(self,name): #定义初始化信息. self.name = name li = Person('李') #实例化Person('李'),给变量li li.age = 20 #再程序没有停止下,将实例属性age传入.动态语言的特点. Person.age = None #这里使用类名来创建一个属性age给类,默认值是None.Python支持的动态属性添加. def eat(self): #定义一个方法,不过这个方法再

在python里如何动态添加类的动态属性呢?

body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI",Tahoma,Helvetica,Sans-Serif,"Microsoft YaHei", Georgia,Helvetica,Arial,sans-serif,宋体, PMingLiU,serif; font-size: 10.5pt; line-height: 1.5;

给python类动态添加方法(method)

群里有人问如何做到 def foo(): pass class Bar(object): pass Bar.set_instance_method(foo) b = Bar() b.foo() 这个其实还是比较简单的, 只要写个函数给类设置属性即可, 可根据需求是否用函数包装下, 或者用staticmethod这个decorator: import functools def foo(): print 'hello world' class Bar(object): def __init__(s

细说python类2——类动态添加方法和slots(转)

先说一下类添加属性方法和实例添加属性和方法的区别, 类添加属性属于加了一个以类为全局的属性(据说叫静态属性),那么以后类的每一个实例化,都具有这个属性.给类加一个方法也如此,以后类的每一个实例化都具备这个方法(但是据说叫动态方法.)但是给实例加一个属性,作用域就是这个实例,是与类没关系的(据说这种属性叫动态属性). Python类的实例可以动态的添加属性.举个例子,声明一个类A >>> class A(object):...   def __init__(self):...     pr

python 面向对象六 动态添加方法 __slots__限制动态添加方法

一.动态添加属性 1 >>> class Student(object): 2 pass 3 4 >>> st = Student() 5 >>> st.name = 'Jack' 6 >>> st.name 7 'Jack' 二.动态给实例添加方法 1 >>> from types import MethodType 2 >>> class Student(object): 3 pass 4 5

python 动态给实例添加属性和方法并使用__slots__

from types import MethodType #创建一个空类class Person(object): __slots__ = ("name", "age", "speak") per = Person()#动态添加属性,这体现了动态语言的特点(灵活)per.name = "tom"print(per.name)#动态添加方法'''def say(self): print("my name is &quo

django-celery动态添加定时任务

为了使用celery替代crontab并做到实时添加定时任务的效果,需要使用django-celery,效果如下图, 来自:https://www.caktusgroup.com/blog/2014/06/23/scheduling-tasks-celery/ 要使用django-celery,需要安装python的以下包:django,celery,django-celery.其中django安装比较麻烦,首先它和python版本相关,django1.7.9和1.8.3都是支持python 2