Get the class that defined a given method in Python

avatar

Borislav Hadzhiev

Last updated: Sep 13, 2022

banner

Photo from Unsplash

Get the class that defined a given method in Python #

To get the class that defined a given method:

  1. Use the inspect.getmro() method to get a tuple of the class's base classes.
  2. Use a for loop to iterate over the collection.
  3. Check if the method is contained in any of the classes.
main.py
import inspect class Person(): def greet(self): print('hello world') class Employee(Person): pass class Developer(Employee): pass d1 = Developer() print(d1.greet.__qualname__) # 👉️ Person.greet def get_class_that_defined_method(method): for cls in inspect.getmro(method.__self__.__class__): if method.__name__ in cls.__dict__: return cls return None # 👇️ <class '__main__.Person'> print(get_class_that_defined_method(d1.greet))

The __qualname__ attribute returns the qualified name of a class, function, method, descriptor or generator instance.

You can use the attribute if you need to get the name of the class that defined the attribute.

main.py
import inspect class Person(): def greet(self): print('hello world') class Employee(Person): pass class Developer(Employee): pass d1 = Developer() print(d1.greet.__qualname__) # 👉️ Person.greet name = d1.greet.__qualname__.split('.')[0] print(name) # 👉️ Person

If you need access to the class object, use the inspect.getmro() method to iterate over the class's base classes.

main.py
import inspect class Person(): def greet(self): print('hello world') class Employee(Person): pass class Developer(Employee): pass d1 = Developer() def get_class_that_defined_method(method): for cls in inspect.getmro(method.__self__.__class__): if method.__name__ in cls.__dict__: return cls return None # 👇️ <class '__main__.Person'> print(get_class_that_defined_method(d1.greet))

The inspect.getmro method returns a tuple of the base classes of a given class.

MRO is an abbreviation for method resolution order.

The provided class is the first element in the tuple and no class appears more than once.
main.py
import inspect class Person(): def greet(self): print('hello world') class Employee(Person): pass class Developer(Employee): pass d1 = Developer() # 👇️ '(<class '__main__.Developer'>, <class '__main__.Employee'>, <class '__main__.Person'>, <class 'object'>) print(inspect.getmro(d1.__class__))

We used a for loop to iterate over the base classes.

On each iteration, we check if the name of the method is present in the dictionary of the class object.

The __name__ attribute returns the name of a class, function, method, descriptor or generator instance.

The __dict__ attribute returns a dictionary containing the object's properties and values.

main.py
import inspect class Person(): def greet(self): print('hello world') class Employee(Person): pass class Developer(Employee): pass d1 = Developer() print(d1.greet.__name__) # 👉️ greet # 👇️ {'greet': <function Person.greet at 0x7fad6d8d5ab0>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None, '__module__': '__main__'} print(Person.__dict__)

Notice that the dictionary of the Person class contains a greet key.

Here is the complete code snippet that returns the class that defined the given method.

main.py
import inspect class Person(): def greet(self): print('hello world') class Employee(Person): pass class Developer(Employee): pass d1 = Developer() def get_class_that_defined_method(method): for cls in inspect.getmro(method.__self__.__class__): if method.__name__ in cls.__dict__: return cls return None # 👇️ <class '__main__.Person'> print(get_class_that_defined_method(d1.greet))
I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.