How to Check If a Class Is a Subclass of Another Class in Python
In Object-Oriented Programming (OOP), inheritance allows a child class to derive attributes and methods from a parent class. Validating these relationships is essential for enforcing type constraints, building plugin architectures, or debugging complex class hierarchies.
This guide explains how to determine if a specific class is a subclass of another using Python's built-in issubclass() function and how to inspect direct lineage using the __bases__ attribute.
Understanding the Class Hierarchy
Before checking relationships, let's define a simple inheritance structure. We will create a base class Animal and two subclasses, Dog and Cat.
class Animal:
def __init__(self, name):
self.name = name
class Dog(Animal):
def speak(self):
print("Woof!")
class Cat(Animal):
def speak(self):
print("Meow!")
In this structure:
Doginherits fromAnimal.Catinherits fromAnimal.DogandCatare siblings (no inheritance relationship between them).
Method 1: Using issubclass() (Recommended)
The built-in function issubclass(class, class_info) is the standard way to check inheritance. It returns True if the first argument is a subclass of the second.
Basic Usage
# ✅ Check if Dog is a subclass of Animal
is_dog_animal = issubclass(Dog, Animal)
print(f"Is Dog a subclass of Animal? {is_dog_animal}")
# ✅ Check if Dog is a subclass of Cat (False)
is_dog_cat = issubclass(Dog, Cat)
print(f"Is Dog a subclass of Cat? {is_dog_cat}")
Output:
Is Dog a subclass of Animal? True
Is Dog a subclass of Cat? False
Checking Multiple Parents
The second argument can be a tuple of classes. The function returns True if the class is a subclass of any item in the tuple.
# ✅ Check if Dog is a subclass of either int or Animal
print(issubclass(Dog, (int, Animal)))
Output:
True
A class is considered a subclass of itself. Therefore, issubclass(Animal, Animal) returns True.
Method 2: Inspecting __bases__ (Direct Parents)
If you need to know the direct parent(s) of a class, rather than the full ancestry, you can inspect the __bases__ attribute. This returns a tuple containing the immediate base classes.
# ✅ Inspecting direct parents
print(f"Dog bases: {Dog.__bases__}")
print(f"Animal bases: {Animal.__bases__}")
Output:
Dog bases: (<class '__main__.Animal'>,)
Animal bases: (<class 'object'>,)
In Python 3, all classes eventually inherit from the built-in object class. This is why Animal.__bases__ shows object.
Common Pitfall: Instances vs. Classes
A frequent error occurs when developers confuse classes (the blueprint) with instances (the object created from the blueprint). issubclass() expects a class, not an instance.
The Error
my_dog = Dog("Buddy")
try:
# ⛔️ Incorrect: Passing an instance ('my_dog') to issubclass
print(issubclass(my_dog, Animal))
except TypeError as e:
print(f"Error: {e}")
Output:
Error: issubclass() arg 1 must be a class
The Solution
If you have an object (instance) and want to check its type, use isinstance() instead.
my_dog = Dog("Buddy")
# ✅ Correct: Check if the INSTANCE is of type Animal
print(f"Is my_dog an instance of Animal? {isinstance(my_dog, Animal)}")
# ✅ Correct: Get the class from the instance, then check subclass
print(f"Is the class of my_dog a subclass? {issubclass(type(my_dog), Animal)}")
Output:
Is my_dog an instance of Animal? True
Is the class of my_dog a subclass? True
Conclusion
Checking class relationships is straightforward in Python:
- Use
issubclass(Child, Parent)for standard inheritance checks. It handles deep inheritance hierarchies correctly. - Use
Class.__bases__if you strictly need to see immediate parents for introspection or documentation generation. - Use
isinstance(object, Class)when checking the type of a specific object instance, rather than the relationship between two classes.