Python isinstance Function
Last modified April 11, 2025
This comprehensive guide explores Python's isinstance function,
which checks if an object is an instance of a class or tuple of classes.
We'll cover basic usage, inheritance, abstract base classes, and practical
examples.
Basic Definitions
The isinstance function returns True if the object
argument is an instance of the classinfo argument. It also works with
inheritance and abstract base classes.
Key characteristics: checks object type, supports inheritance hierarchy,
accepts type tuples, and works with abstract base classes via registration.
More flexible than type() checks.
Basic Type Checking
Here's simple usage with built-in types showing how isinstance
verifies object types against single classes and tuples of classes.
num = 42
name = "Alice"
values = [1, 2, 3]
print(isinstance(num, int)) # True
print(isinstance(name, str)) # True
print(isinstance(values, list)) # True
# With tuple of types
print(isinstance(num, (int, float))) # True
print(isinstance(3.14, (int, float))) # True
print(isinstance("text", (int, float))) # False
This example shows isinstance with different built-in types.
It returns True when the object matches the specified type.
The tuple version checks against multiple types at once, returning True
if any type matches. This is more concise than multiple or conditions.
Inheritance Checking
isinstance works with inheritance hierarchies, recognizing
subclass instances as valid for parent classes. This example demonstrates
polymorphic behavior.
class Animal:
pass
class Dog(Animal):
pass
class Cat(Animal):
pass
my_dog = Dog()
my_cat = Cat()
print(isinstance(my_dog, Dog)) # True
print(isinstance(my_dog, Animal)) # True (inheritance)
print(isinstance(my_cat, Dog)) # False
print(isinstance(my_cat, Animal)) # True
The example shows how isinstance respects inheritance. A Dog
instance is considered both a Dog and an Animal.
This behavior makes isinstance more useful than type()
for polymorphism, as it works with the entire class hierarchy.
Abstract Base Classes
isinstance works with abstract base classes (ABCs) from the
collections.abc module, checking for interface compliance.
from collections.abc import Sequence, Iterable
my_list = [1, 2, 3]
my_dict = {'a': 1, 'b': 2}
print(isinstance(my_list, Sequence)) # True
print(isinstance(my_list, Iterable)) # True
print(isinstance(my_dict, Sequence)) # False
print(isinstance(my_dict, Iterable)) # True
This checks if objects implement specific abstract interfaces. list
is both a Sequence and Iterable, while dict
is only Iterable.
ABC checks are useful for verifying objects support required operations
(like indexing for Sequence) without checking concrete types.
Custom Class Checking
You can use isinstance with custom classes and multiple inheritance.
This example shows complex class relationships.
class Vehicle:
pass
class Engine:
pass
class Car(Vehicle, Engine):
pass
class Boat(Vehicle):
pass
my_car = Car()
my_boat = Boat()
print(isinstance(my_car, Vehicle)) # True
print(isinstance(my_car, Engine)) # True
print(isinstance(my_boat, Engine)) # False
print(isinstance(my_boat, (Engine, Vehicle))) # True
The example demonstrates multiple inheritance checking. Car
inherits from both Vehicle and Engine, so
isinstance returns True for both.
The tuple check shows how to test for multiple possible base classes in one operation, which is cleaner than separate checks.
Dynamic Type Checking
This example shows runtime type checking in a function that processes
different input types differently using isinstance.
def process_data(data):
if isinstance(data, str):
return f"Processed string: {data.upper()}"
elif isinstance(data, (int, float)):
return data * 2
elif isinstance(data, dict):
return {k.upper(): v for k, v in data.items()}
else:
return f"Unsupported type: {type(data).__name__}"
print(process_data("hello")) # Processed string: HELLO
print(process_data(42)) # 84
print(process_data({'a': 1})) # {'A': 1}
print(process_data([1, 2, 3])) # Unsupported type: list
The function uses isinstance to handle different input types
appropriately. This pattern is common in functions that need to accept
multiple types.
Note how it handles numeric types with a tuple check and provides a fallback for unsupported types. This is more maintainable than separate functions.
Best Practices
- Prefer over type():
isinstancehandles inheritance - Use ABCs for interfaces: Check capabilities rather than concrete types
- Limit type checking: Use polymorphism when possible
- Document expected types: Make type requirements clear
- Consider type hints: For static type checking complement
Source References
Author
List all Python tutorials.