繁体   English   中英

找出父级中的重写方法

[英]Find out overridden method in parent

我熟悉 OOP,并且了解我们可以从基础 class 继承并在子 class 中扩展user_call_api ,为其添加更多定义。 但我想知道在父 class 中有没有一种方法,我们可以找出

  • 哪些方法被覆盖(由子类)
  • 已覆盖该方法的(子)类的名称
class Parent:

    def call_api(self):
        print("API is called")

    def use_call_api(self):
        # if it's overridden, find out in parent,
        # do something and then
        self.call_api()

        # if it's not overridden
        self.call_api()


class Child(Parent):

    def call_api(self):
        print("call_api")


class Child2(Parent):

    def call_api(self):
        print("call_api2")


class Child3(Parent):

    def call_api(self):
        print("call_ap3")

    def use_call_api(self):
        print("custom call_api")

您可以拥有一个元类,它将覆盖__new__ dunder 方法并将必要的信息(方法名称和覆盖它的 class 名称)保存到它的 singleton 属性中。

import re


class Inspect(type):
    implementations = {}

    def __new__(mcs, cls, args, kwargs):
        for attr in kwargs.keys():
            if not re.match(r"^__\w+__$", attr):
                mcs.implementations[attr] = (*mcs.implementations.get(attr, ()), cls)
        return type(cls, args, kwargs)

类(主要是从Parent继承的子类)应该使用Inspect元类。

应用程序启动后, Inspect.implementations将位于其最终 state 中,并且所有类和函数都在动态 memory 中声明以准备执行脚本。 因此,您可以在Parent中声明一个附加方法,以获取覆盖当前方法的类列表,甚至该方法是否被覆盖。

import inspect


class Parent:

    @staticmethod
    def overridden() -> tuple:
        return Inspect.implementations.get(inspect.stack()[1].function, ())

    def call_api(self):
        print("API is called")

    def use_call_api(self):
        # if it's overridden, find out in parent,
        if self.overridden():
            print("use_call_api has been overridden in", self.overridden())

            # do something and then
            self.call_api()

        # if it's not overridden
        self.call_api()


class Child(Parent, metaclass=Inspect):

    def call_api(self):
        print("call_api")

    def use_call_api(self):
        pass


if __name__ == "__main__":
    p = Parent()
    p.use_call_api()

如果你运行上面的代码,那么你会看到当Child重写use_call_api方法时,那么被Parent的相同方法调用的overridden方法将包含Child ,表明它重写了该方法。 如果我们不为Child实现use_call_api ,则overridden将返回一个空元组, if self.overridden()条件不起作用并将通过案例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM