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)

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值