Python: Show all subclasses of a class

class.__subclasses__()
returns a list of the direct subclasses of a given class:
In [1]: class Base: pass
...: class Alpha(Base): pass
In [2]: Base.__subclasses__()
Out[2]: [__main__.Alpha]
This function picks up subclasses wherever they are defined. That can make it useful for tracking down code to edit, as I showed recently.
But __subclasses__()
does not descend the inheritance hierarchy, so it does not return subclasses of subclasses:
In [1]: class Base: pass
...: class Alpha(Base): pass
...: class Beta(Alpha): pass
In [2]: Base.__subclasses__()
Out[2]: [__main__.Alpha]
To get all subclasses, use this recursive wrapper:
def recursive_subclasses(klass):
"""
Yield all subclasses of the given class, per:
https://adamj.eu/tech/2024/05/10/python-all-subclasses/
"""
seen = set()
for subclass in klass.__subclasses__():
yield subclass
for subsubclass in recursive_subclasses(subclass):
if subsubclass not in seen:
seen.add(subsubclass)
yield subsubclass
It yields and all subclasses and then recursively from their subclasses. It uses a set, seen
, to avoid duplicates , which arise with diamond-style inheritance.
For example:
In [4]: list(recursive_subclasses(Base))
Out[4]: [__main__.Alpha, __main__.Beta]
As recursive_subclasses()
is a generator function, list()
is required to get all the classes at once.
Read my book Boost Your Django DX, freshly updated in November 2024.
One summary email a week, no spam, I pinky promise.
Related posts:
- Python: Make line number paths with
inspect
- unittest’s new context methods in Python 3.11 (with backports)
- Django: Pinpoint upstream changes with Git
Tags: python