How to detect method overloading in subclasses in python? How to detect method overloading in subclasses in python? python python

How to detect method overloading in subclasses in python?


You can use your own decorator. But this is a trick and will only work on classes where you control the implementation.

def override(method):  method.is_overridden = True  return methodclass Super:   def __init__(self):      if hasattr(self.method, 'is_overridden'):         print 'different'      else:         print 'same'   @classmethod   def method(cls):      passclass Sub1(Super):   @override   def method(self):      print 'hi'class Sub2(Super):   passSuper() # should be sameSub1() # should be differentSub2() # should be same>>> same>>> different>>> same


It seems simplest and sufficient to do this by comparing the common subset of the dictionaries of an instance and the base class itself, e.g.:

def detect_overridden(cls, obj):  common = cls.__dict__.keys() & obj.__class__.__dict__.keys()  diff = [m for m in common if cls.__dict__[m] != obj.__class__.__dict__[m]]  print(diff)def f1(self):  passclass Foo:  def __init__(self):    detect_overridden(Foo, self)  def method1(self):    print("Hello foo")  method2=f1class Bar(Foo):  def method1(self):    print("Hello bar")  method2=f1 # This is pointless but not an override#  def method2(self):#    passb=Bar()f=Foo()

Runs and gives:

['method1'][]


In reply to answer https://stackoverflow.com/a/9437273/1258307, since I don't have enough credits yet to comment on it, it will not work under python 3 unless you replace im_func with __func__ and will also not work in python 3.4(and most likely onward) since functions no longer have the __func__ attribute, only bound methods.

EDIT: Here's the solution to the original question(which worked on 2.7 and 3.4, and I assume all other version in between):

    class Super:        def __init__(self):            if self.method.__code__ is Super.method.__code__:                print('same')            else:                print('different')        @classmethod        def method(cls):            pass    class Sub1(Super):        def method(self):            print('hi')    class Sub2(Super):        pass    Super() # should be same    Sub1() # should be different    Sub2() # should be same

And here's the output:

samedifferentsame