Skip to main content

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:

  • Dog inherits from Animal.
  • Cat inherits from Animal.
  • Dog and Cat are siblings (no inheritance relationship between them).

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
note

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'>,)
tip

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:

  1. Use issubclass(Child, Parent) for standard inheritance checks. It handles deep inheritance hierarchies correctly.
  2. Use Class.__bases__ if you strictly need to see immediate parents for introspection or documentation generation.
  3. Use isinstance(object, Class) when checking the type of a specific object instance, rather than the relationship between two classes.