(python)父类调用注册:当子类覆写了父类方法后,在调用子类方法时自动调用其父类方法

设计思路

在新建类实例时,为子类方法添加装饰。因此任务拆解为对子类实例创建的检测与装饰的添加。

def mustcall(func):
    if not hasattr(mustcall, "classname2fun"):
        setattr(mustcall, "classname2fun", dict())  # Parent.func -> <Parent.func object at ...>
        setattr(mustcall, "classnames", list())  # 注册的类名

    classname2fun = getattr(mustcall, "classname2fun")
    classnames = getattr(mustcall, "classnames")
    classnames.append(func.__qualname__.split('.')[0])
    classname2fun[func.__qualname__] = func  # Parent.func -> <Parent.func object at ...>

    return func


class MustCall:
    def __new__(cls):
        if cls.__name__ != __class__.__name__:  # 检测到 MustCall的子类
            if cls.__name__ not in getattr(mustcall, "classnames"):  # 检测到 集成MustCAll基类的类的子类
                # 获取父类的名称,即父类的父类含有MustCall
                baseclassname = None
                for base in cls.__bases__:
                    if any(base_.__name__ == __class__.__name__ for base_ in base.__bases__):
                        baseclassname = base.__name__
                # 对子类进行方法封装
                for classname, func in getattr(mustcall, "classname2fun").items():
                    if classname.split(".")[0] == baseclassname:
                        subfunc = getattr(cls, func.__name__)

                        def newfunc(self, *args, **kw):
                            func(self, *args, **kw)
                            subfunc(self, *args, **kw)

                        setattr(cls, func.__name__, newfunc)

        return super().__new__(cls)

用法:

class Parent(MustCall):
    @mustcall
    def f(self):
        print("parent call f")


class Child(Parent):
    def f(self):
        print(f"child's f says:")


p: Parent = Parent()
p.f()
p: Parent = Child()
p.f()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值