19

Is there a way to get all overriden functions of a subclass in Python?

Example:

class A:
    def a1(self):
        pass

    def a2(self):
        pass


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

    def b1(self):
        pass

Here, I would like to get a list ["a2"] for an object of class B (or for the class object itself) since class B overrides only a single method, namely a2.

pppery
  • 3,731
  • 22
  • 33
  • 46

3 Answers3

18

You can access the parent classes with cls.__bases__, find all attributes of the parents with dir, and access all the attributes of the class itself with 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'}
Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
3

You can make use of the __mro__ tuple, which holds the method resolution order.

For your example:

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

So you could loop over that tuple and check if a B method is also in one of the other classes.

Adelin
  • 7,809
  • 5
  • 37
  • 65
-1
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***
wjandrea
  • 28,235
  • 9
  • 60
  • 81
Manish Kumar
  • 554
  • 4
  • 7
  • 2
    I think you misunderstood the question. Classes `A` and `B` can't be modified. OP wants to know which of `B`'s methods override one of `A`'s methods. – wjandrea Oct 24 '19 at 21:10