Python Forum

Full Version: Determine whether a method was overridden
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Is the following a good idea, to determine whether a method was overridden with something "real" (and so is not more an "abstract" method which should not be called)?


class Base(object):
    def f(self):
        raise NotImplementedError()

    def hasF(self):
        return self.f != Base.f

class Derived(Base):
    def f(self):
        pass
Or should I instead explicitly define hasF()?

class Base(object):
    def f(self):
        raise NotImplementedError()

    def hasF(self):
        return False

class Derived(Base):
    def f(self):
        pass

    def hasF(self):
        return True

Hm, I've realized that self.f != Base.f does not do what it should. How to check if a method was overridden?
Is this what you want?
class Base(object):
    def f(self):
        raise NotImplementedError()

    def hasF(self):
        return  isinstance(self.f, object)


class Derived(Base):
    def f(self):
        pass

b = Base()
if b.hasF():
    print('Indeed it is')
else:
    print('Nope')
(Nov-14-2016, 06:43 PM)Larz60+ Wrote: [ -> ]Is this what you want?
class Base(object):
    def f(self):
        raise NotImplementedError()

    def hasF(self):
        return  isinstance(self.f, object)


class Derived(Base):
    def f(self):
        pass

b = Base()
if b.hasF():
    print('Indeed it is')
else:
    print('Nope')

I do not understand why you check whether self.f is an instance of object. I need to check if f was overridden (in a derived class).
That's not right - I have to go out for a few hours.
If someone doesn't answer before then, I'll do so when I get back
Does it need to be callable if it's just going to raise an error? What if "f" defaults to just being None?
>>> class Base(object):
...   def __init__(self):
...     self.f = None
...   def hasF(self):
...     return self.f is not None
...
>>> class Derived(Base):
...   def __init__(self):
...     pass
...   def f(self):
...     return 'spam'
...
>>> x = Derived()
>>> x.hasF()
True
>>> x.f()
'spam'
>>> y = Base()
>>> y.hasF()
False
>>> y.f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable
I think this is what you want:

class Base(object):

    def f(self):
        raise NotImplementedError()
 
    @classmethod
    def has_f(cls):
        return cls.f != Base.f
 
class Derived(Base):

    def f(self):
        pass

class Inherit(Base):
    
    def g(self):
        pass

if __name__ == '__main__':
    print(Base.has_f())
    print(Derived.has_f())
    print(Inherit.has_f())
This returns True if the method has been overridden. The classmethod decorator makes the class be passed as the first parameter, not the instance.
What is not clear in the question is "what" needs to know... An instance of the derived class? Code external to both base and derived classes?

And why is this needed in the first place? Maybe you should reconsider your design?