Get class that defined method Get class that defined method python python

Get class that defined method


import inspectdef get_class_that_defined_method(meth):    for cls in inspect.getmro(meth.im_class):        if meth.__name__ in cls.__dict__:             return cls    return None


Thanks Sr2222 for pointing out I was missing the point...

Here's the corrected approach which is just like Alex's but does not require to import anything. I don't think it's an improvement though, unless there's a huge hierarchy of inherited classes as this approach stops as soon as the defining class is found, instead of returning the whole inheritance as getmro does. As said, this is a very unlikely scenario.

def get_class_that_defined_method(method):    method_name = method.__name__    if method.__self__:            classes = [method.__self__.__class__]    else:        #unbound method        classes = [method.im_class]    while classes:        c = classes.pop()        if method_name in c.__dict__:            return c        else:            classes = list(c.__bases__) + classes    return None

And the Example:

>>> class A(object):...     def test(self): pass>>> class B(A): pass>>> class C(B): pass>>> class D(A):...     def test(self): print 1>>> class E(D,C): pass>>> get_class_that_defined_method(A().test)<class '__main__.A'>>>> get_class_that_defined_method(A.test)<class '__main__.A'>>>> get_class_that_defined_method(B.test)<class '__main__.A'>>>> get_class_that_defined_method(C.test)<class '__main__.A'>>>> get_class_that_defined_method(D.test)<class '__main__.D'>>>> get_class_that_defined_method(E().test)<class '__main__.D'>>>> get_class_that_defined_method(E.test)<class '__main__.D'>>>> E().test()1

Alex solution returns the same results. As long as Alex approach can be used, I would use it instead of this one.


I don't know why no one has ever brought this up or why the top answer has 50 upvotes when it is slow as hell, but you can also do the following:

def get_class_that_defined_method(meth):    return meth.im_class.__name__

For python 3 I believe this changed and you'll need to look into .__qualname__.