Problem Formulation
Given a class by name (string). How to find all the subclasses of the given class?

Example: Here’s an example scenario with a subclass hierarchy.
class Parent:
pass
class Daughter(Parent):
pass
class Son(Parent):
pass
class Grandson(Son):
pass
Desired outputs: Next, let’s quickly establish what you want to accomplish with two examples.
Given:SonResult:GrandsonGiven:ParentResult:Daughter, Son
For the most basic cases, we don’t assume a recursive solution requirement, so we don’t consider Grandson also a subclass of Parent.
Solution If We Have the Class Object, Not Only the Class Name
Assume (for now), we have the class object. We’re looking at a slightly more complicated case without this assumption in the next section of this article.
In this case, we can simply get all subclasses of the class using the my_class.__subclasses__() magic method:
class Parent:
pass
class Daughter(Parent):
pass
class Son(Parent):
pass
class Grandson(Son):
pass
print(Parent.__subclasses__())
# [<class '__main__.Daughter'>, <class '__main__.Son'>]If you only need a list of all names of subclasses, and not the whole clutter around the output, you can use a list comprehension statement like so:
names = [cls.__name__ for cls in Parent.__subclasses__()] print(names) # ['Daughter', 'Son']
Recursive for All Subclasses
You can get all direct and indirect subclasses (if hierarchical inheritance is used) using a recursive approach:
- Create a function
subclass_recursive()that takes one argument: the base class from which the subclasses should be found. - Find all direct subclasses using the
__subclasses__()magic method. - Find all indirect subclasses by calling the function recursively.
- Return the concatenation of direct and indirect subclasses to the caller.
If you need a refresher on recursion, check out my in-depth tutorial here.
Let’s dive into the code!
class Parent:
pass
class Daughter(Parent):
pass
class Son(Parent):
pass
class Grandson(Son):
pass
class GrandGrandSon(Son):
pass
def subclasses_recursive(cls):
direct = cls.__subclasses__()
indirect = []
for subclass in direct:
indirect.extend(subclasses_recursive(subclass))
return direct + indirect
print(subclasses_recursive(Parent))
The output is the list of all subclasses:
[<class '__main__.Daughter'>, <class '__main__.Son'>, <class '__main__.Grandson'>, <class '__main__.GrandGrandSon'>]
Again, if you need to have only the class names as strings, use list comprehension with the __name__ special attribute on the subclasses.
names = [cls.__name__ for cls in subclasses_recursive(Parent)] print(names) # ['Daughter', 'Son', 'Grandson', 'GrandGrandSon']
If We Only Have the String Name of the Class
You can use the globals() built-in function to find out the class object, given its name:
# Get class given name of class: base_name = 'Parent' base_class = globals()[base_name]
Feel free to watch my background video on the function next:
If this doesn’t work, you may want to check out the locals() function too.
# Get class given name of class: base_name = 'Parent' base_class = locals()[base_name]
Finally, another way to get the class given its full path is outlined here:
import importlib
module_name, _, base_name = name.rpartition('.')
module = importlib.import_module(module_name)
base_class = getattr(module, base_name)Putting It All Together
class Parent:
pass
class Daughter(Parent):
pass
class Son(Parent):
pass
class Grandson(Son):
pass
class GrandGrandSon(Son):
pass
# Get class given name of class:
base_name = 'Parent'
base_class = globals()[base_name]
# Get list of direct subclasses:
print(base_class.__subclasses__())
# [<class '__main__.Daughter'>, <class '__main__.Son'>]
# Get list of direct subclass names:
names = [cls.__name__ for cls in base_class.__subclasses__()]
print(names)
# ['Daughter', 'Son']
# Get list of direct and indirect subclasses:
def subclasses_recursive(cls):
direct = cls.__subclasses__()
indirect = []
for subclass in direct:
indirect.extend(subclasses_recursive(subclass))
return direct + indirect
# Get list of direct and indirect subclasse names:
names = [cls.__name__ for cls in subclasses_recursive(base_class)]
print(names)
# ['Daughter', 'Son', 'Grandson', 'GrandGrandSon']