Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get overridden functions of subclass

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.

like image 758
Andreas Schörgenhumer Avatar asked Oct 24 '19 12:10

Andreas Schörgenhumer


People also ask

Which methods must be overridden in the subclass?

Subclass must override methods that are declared abstract in the superclass, or the subclass itself must be abstract. Writing Abstract Classes and Methods discusses abstract classes and methods in detail.

When a method is overridden in a subclass?

The ability of a subclass to override a method allows a class to inherit from a superclass whose behavior is "close enough" and then to modify behavior as needed. The overriding method has the same name, number and type of parameters, and return type as the method that it overrides.

Can a subclass member be overridden?

If a method cannot be inherited, then it cannot be overridden. A subclass within the same package as the instance's superclass can override any superclass method that is not declared private or final. A subclass in a different package can only override the non-final methods declared public or protected.

How do you invoke an overridden superclass method from a subclass?

The overridden method shall not be accessible from outside of the classes at all. But you can call it within the child class itself. to call a super class method from within a sub class you can use the super keyword.


2 Answers

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'}
like image 195
Aran-Fey Avatar answered Oct 11 '22 07:10

Aran-Fey


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.

like image 45
Adelin Avatar answered Oct 11 '22 06:10

Adelin