【问题标题】:Get overridden functions of subclass获取子类的覆盖函数
【发布时间】:2019-10-24 12:02:25
【问题描述】:

有没有办法在 Python 中获取子类的所有重写函数?

例子:

class A:
    def a1(self):
        pass

    def a2(self):
        pass


class B(A):
    def a2(self):
        pass

    def b1(self):
        pass

在这里,我想为B 类的对象(或类对象本身)获取一个列表["a2"],因为B 类只覆盖了一个方法,即a2

【问题讨论】:

    标签: python reflection overriding subclass


    【解决方案1】:

    你可以用cls.__bases__访问父类,用dir找到父类的所有属性,用vars访问类本身的所有属性:

    def get_overridden_methods(cls):
        # collect all attributes inherited from parent classes
        parent_attrs = set()
        for base in cls.__bases__:
            parent_attrs.update(dir(base))
    
        # find all methods implemented in the class itself
        methods = {name for name, thing in vars(cls).items() if callable(thing)}
    
        # return the intersection of both
        return parent_attrs.intersection(methods)
    
    >>> get_overridden_methods(B)
    {'a2'}
    

    【讨论】:

    • vars 是我缺少的东西。非常感谢(令人难以置信的)快速回答!
    • parent_attrs 如果需要,可以在一行中:parent_attrs = {a for b in cls.__bases__ for a in dir(b)}
    【解决方案2】:

    您可以使用__mro__ 元组,它保存方法解析顺序。

    你的例子:

    >>> B.__mro__
    ( <class '__main__.B'>, <class '__main__.A'>, <class 'object'>) 
    

    因此,您可以遍历该元组并检查 B 方法是否也在其他类之一中。

    【讨论】:

    • 这不会排除预定义的方法,就像任何 dunder 方法一样,__init__, __eq__, ....... etc
    【解决方案3】:
    class A:
    
        def a1(self):
            pass
    
        def a2(self):
            pass
    
    
    class B(A):
    
        def a2(self):
            super().a2()  
            pass
    
        def b1(self):
            pass
    obj = B()
    
    obj.a2()   # ***first give the output of parent class then child class***
    

    【讨论】:

    • 我认为您误解了这个问题。类 AB 不能修改。 OP 想知道B 的哪些方法会覆盖A 的方法之一。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多