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