当前位置: 首页 > news >正文

python 的动态类、动态对象类(我自己取的名)

python的奇技淫巧

来源:当前已经有多个不同的类,各个类都是同一个基类,这时候需要一个特殊的动态类,可以在已有的各种类之间进行切换

如下面举例的A、B两个类,此时需要一个动态的类,与其平级,但又可以在A、B之间来回切换

一、动态类

设计思路:动态类中,初始化的时候将另一个类的方法动态设置到该动态类中,重置的时候清楚掉这些方法,动态类就实现了

import inspect
from functools import partial


class A(object):
    classParamA = 2

    def __call__(self, *args, **kwargs):
        print("===================A", args, kwargs)

    def __init__(self):
        self.paramA = 1
        print("====A")

    def addA(self, a, b):
        print("A类的加法", a + 2 * b + self.paramA)

    def minA(self, a, b):
        print("A类的减法", a - 2 * b)


class B(object):
    classParamB = 2

    def __init__(self):
        self.paramB = 1
        print("====B")

    def addB(self, a, b):
        print("B类的加法", a + b + self.paramB)

    def minB(self, a, b):
        print("B类的减法", a - b)


classMap = {"A": A, "B": B}


class DynamicClass(object):
    """可以动态类"""

    def __init__(self, type):
        self.setClass(type)

    def setClass(self, type):
        self.type = type
        cls = classMap[type]
        for funcInfo in inspect.getmembers(cls, inspect.isfunction):
            funcName = funcInfo[0]
            func = funcInfo[1]
            if funcName != "__init__":
                setattr(self, funcName, partial(func, self))
        cls.__init__(self)

    def resetClass(self, type):
        cls = classMap[self.type]
        for funcInfo in inspect.getmembers(cls, inspect.isfunction):
            funcName = funcInfo[0]
            if funcName != "__init__":
                delattr(self, funcName)
        self.setClass(type)


a = DynamicClass("A")
a.addA(11, 11)

a.resetClass("B")
a.addB(11, 11)

运行结果如下:
在这里插入图片描述

二、动态对象类

为什么称之为动态对象类,因为它相当于是一个类中存有一个动态变化的对象,这个对象依据传入的类名而变动。
设计思路:
1、首先,我们知道 __ getattribute __ 方法在调用类中所有的属性时都会被调用到,并且通过该方法获得对象(python中皆为对象,包括方法也是)
2、我们在调用方法的时候,通过 __ getattribute __ 方法,获取到对象的方法并调用

# -*- coding: utf-8 -*-
import inspect
from functools import partial


class A(object):
    classParamA = 2

    def __call__(self, *args, **kwargs):
        print("===================A", args, kwargs)

    def __init__(self):
        self.paramA = 1
        print("====A")

    def addA(self, a, b):
        print("A类的加法", a + 2 * b + self.paramA)

    def minA(self, a, b):
        print("A类的减法", a - 2 * b)

    def multi(self, a, b):
        print("A类的乘法", a * b)


class B(object):
    classParamB = 2

    def __init__(self):
        self.paramB = 1
        print("====B")

    def addB(self, a, b):
        print("B类的加法", a + b + self.paramB)

    def minB(self, a, b):
        print("B类的减法", a - b)

    def multi(self, a, b):
        print("B类的乘法", a * b)


classMap = {"A": A, "B": B}


class DynamicClass(object):
    """可以动态类"""

    def __init__(self, dynamicType):
        self.obj = None
        self.dynamicType = None
        self.resetClass(dynamicType)

    def __getattribute__(self, *args, **kwargs):
        """ Return getattr(self, name). """
        if args[0] not in ["resetClass", "type", "obj", "__dict__", "multi"]:
            return self.obj.__getattribute__(*args, **kwargs)
        return super(DynamicClass, self).__getattribute__(*args, **kwargs)

    def __getattr__(self, item):
        """如果有必要,可以在这里做特殊处理"""
        return self.__dict__[item]

    def __setattr__(self, key, value):
        """如果有必要,可以在这里做特殊处理"""
        self.__dict__[key] = value

    def resetClass(self, dynamicType, *args, **kwargs):
        self.dynamicType = dynamicType
        cls = classMap.get(dynamicType)
        if cls:
            self.obj = cls(*args, **kwargs)

    def multi(self, a, b):
        """要做一些骚操作"""
        a = a + 1
        self.obj.multi(a, b)


a = DynamicClass("A")
a.addA(11, 11)
a.minA(11, 11)
a.multi(11, 11)

a.resetClass("B")
a.addB(11, 11)
a.minB(11, 11)
a.multi(11, 11)

需要注意的点:在 __ getattribute __ 中,我们需要把动态对象类中的原有方法以及对象(就是该类中的原有属性)过滤掉,否则会因为循环调用导致python崩溃。

    def __getattribute__(self, *args, **kwargs):
        """ Return getattr(self, name). """
        if args[0] not in ["resetClass", "type", "obj", "__dict__", "multi"]:
            return self.obj.__getattribute__(*args, **kwargs)
        return super(DynamicClass, self).__getattribute__(*args, **kwargs)

运行结果如下:
在这里插入图片描述

相关文章:

  • 上海网站建设y021/厦门seo厦门起梦
  • dede珠宝商城网站源码/seo快速排名百度首页
  • 住房和城乡建设部网站监理工程师/站点搜索
  • 千家美装饰怎么样/爱站网站长seo综合查询
  • 自己制作的网站模板以后可以修改吗/抖音营销
  • 唐河企业网站制作价格/广州百度推广优化排名
  • Go项目优化——动态缓存Redis的使用
  • Dijkstra算法——单源最短路径(指定一个节点(源点)到其余各个顶点的最短路径)
  • 【力扣/牛客刷题】27. 移除元素 || 26. 删除有序数组中的重复项 || 88. 合并两个有序数组
  • MATLAB | 绘图复刻(二) | 折线图+误差棒+柱状图+散点抖动+灰色背景+图片叠加
  • ASP.NET公司企业网站源码
  • 文件IO操作笔记
  • 【JAVA程序设计】(C00045)基于Springboot+vue应急知识在线考试系统
  • Xilinx HLS基础介绍(一)
  • 谈一谈当前嵌入式系统安全面临的挑战
  • vite+vue3+ts项目集成vue-router、axios封装、sass、element-plus及icon
  • Java多线程【状态与安全问题】
  • Python编程 变量与常量