문제

I know that in Python, given a class ClassA, with

inspect.getmembers(ClassA, predicate=inspect.ismethod)

I can iterate over the different methods present in ClassA. Inherited methods are also gathered, which is convenient in my case. But what I would need is, given a particular method method1 of ClassA, to get the class from which ClassA inherited method1. It might be ClassA itself, or any of its parents/grandparents. I thought I could recursively traverse the __bases__ attribute, looking for the method1 attribute at each step. But maybe this functionality is already implemented somewhere. Is there another way?

도움이 되었습니까?

해결책

Look through the MRO (Method Resolution Order), using inspect.getmro() (which works on both old and new-style classes):

def class_for_method(cls, method):
    return next((c for c in inspect.getmro(cls) 
                 if method.__func__ in vars(c).values()), None)

There is currently no stdlib method to do this search for you, no.

Demo:

>>> import inspect
>>> def class_for_method(cls, method):
...     return next((c for c in inspect.getmro(cls) 
...                  if method.__func__ in vars(c).values()), None)
... 
>>> class Base1(object):
...     def foo(self): pass
... 
>>> class Base2(object):
...     pass
... 
>>> class ClassA(Base1, Base2):
...     pass
... 
>>> class_for_method(ClassA, ClassA.foo)
<class '__main__.Base1'>

If no base class is found, the above expression returns None:

>>> class Bar:
...     def spam(): pass
... 
>>> class_for_method(ClassA, Bar.spam) is None
True
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top