Search code examples
pythoninheritanceoverridingintrospection

How do I check if a method was overwritten by a child class?


I want to be able to check if a child class has overwritten a method. For example,

class Foo:
    def __init__(self):
        # Is there something following this sort of spec?
        print("overridden" if self.bar != Foo.bar else "not overridden")
    def bar(self):
        return 0

An inherited method that overwrites bar might be:

class Kung(Foo):
    def __init__(self):
        super(Kung, self).__init__()
    def bar(self):
        return 1

In this case, Kung() should print "overridden", but Foo() should print "not overridden". Can I check whether bar was overwritten in the __init__ of Foo without checking the return value?


Solution

  • This is a very strange thing to do. I question the design that would require this. In any case, you could check something like:

    class Foo:
        def __init__(self):
            try:
                bar = type(self).bar
            except AttributeError:
                bar = None
            if bar is None or bar is Foo.bar:
                print("not overriden")
            else:
                print("overridden")
    
        def bar(self): return 0
    

    This works because you are checking for bar on the class objects. If you use some_instance.some_method then that creates a new method object on each invocation, which is why your approach won't work.

    Consider:

    >>> class Foo:
    ...     def bar(self): pass
    ...
    >>> foo = Foo()
    >>> foo.bar is foo.bar
    False
    

    However,

    >>> Foo.bar is Foo.bar
    True