isinstance() is Python’s built-in function for type checking — it returns True if an object is an instance of a specified class or any of its subclasses (or a tuple of classes), and False otherwise. Unlike type(obj) is Class, isinstance() supports inheritance hierarchies, making it the correct and safe way to check types in polymorphic code. In 2026, isinstance() remains a cornerstone in data science (validating pandas/Polars/Dask objects, type guards in pipelines), software engineering (protocol checks, duck typing, error handling), and modern Python (typing.Protocol, structural subtyping) — enabling robust, flexible, and maintainable code.
Here’s a complete, practical guide to using isinstance() in Python: basic checks, tuple of classes, real-world patterns (earthquake data validation, dynamic dispatch, type-safe pipelines), and modern best practices with type hints, performance, inheritance, and integration with Dask/Polars/pandas/dataclasses/typing.
Basic isinstance() — check single class or tuple of classes.
class Shape: pass
class Rectangle(Shape): pass
class Circle(Shape): pass
r = Rectangle()
print(isinstance(r, Rectangle)) # True
print(isinstance(r, Shape)) # True (inheritance)
print(isinstance(r, (Circle, Shape))) # True (tuple check)
print(isinstance(r, int)) # False
# Built-in types
print(isinstance(42, int)) # True
print(isinstance("hello", str)) # True
print(isinstance([1,2], list)) # True
print(isinstance(3.14, (int, float))) # True
Real-world pattern: type-safe earthquake data processing — validate inputs & dispatch dynamically.
import pandas as pd
import dask.dataframe as dd
import polars as pl
def process_data(data):
if isinstance(data, pd.DataFrame):
print("Processing pandas DataFrame")
return data[data['mag'] >= 7.0]
elif isinstance(data, dd.DataFrame):
print("Processing Dask DataFrame")
return data[data['mag'] >= 7.0].compute()
elif isinstance(data, pl.DataFrame):
print("Processing Polars DataFrame")
return data.filter(pl.col('mag') >= 7.0)
else:
raise TypeError(f"Unsupported data type: {type(data)}")
# Usage examples
df_pd = pd.read_csv('earthquakes.csv')
df_dask = dd.read_csv('earthquakes.csv')
df_pl = pl.read_csv('earthquakes.csv')
strong_pd = process_data(df_pd)
strong_dask = process_data(df_dask)
strong_pl = process_data(df_pl)
Advanced usage — Protocol, Union types, custom classes, and dynamic checks.
from typing import Protocol, Union
class HasMag(Protocol):
mag: float
def is_strong(event: HasMag) -> bool:
if not isinstance(event.mag, (int, float)):
raise TypeError("mag must be numeric")
return event.mag >= 7.0
class Quake:
def __init__(self, mag):
self.mag = mag
q = Quake(7.5)
print(is_strong(q)) # True (structural typing via Protocol)
# Union type check
def check_numeric(value: Union[int, float, complex]):
if not isinstance(value, (int, float, complex)):
raise TypeError("Not numeric")
return True
Best practices for isinstance() in Python & data workflows. Prefer isinstance(obj, Class) — over type(obj) is Class (handles inheritance). Modern tip: use Polars/Dask — isinstance(df, (pd.DataFrame, dd.DataFrame, pl.DataFrame)) for multi-backend code. Use tuple for multiple types — isinstance(x, (int, float)). Add type hints — def process(df: Union[pd.DataFrame, dd.DataFrame]) -> None. Use isinstance() in guards — early type checks prevent errors. Use isinstance() with typing.Protocol — structural typing (duck typing with safety). Use isinstance() in metaclasses — dynamic class checks. Use isinstance(obj, type) — for type objects. Use isinstance(obj, (type1, type2)) — OR logic. Avoid isinstance() in tight loops — cache result. Use typing.get_origin()/get_args() — for generic type inspection (advanced). Use inspect.isclass(obj) — check if object is class. Use inspect.isfunction(obj) — check function. Use inspect.ismethod(obj) — check method. Use inspect.isbuiltin(obj) — check built-in. Use inspect.isinstance(obj, type) — same as isinstance. Use hasattr(obj, '__call__') — check callability (less reliable than callable()). Use callable(obj) — preferred for callability check.
isinstance(obj, classinfo) checks if an object is an instance of a class or tuple of classes — handles inheritance, supports Protocol for structural typing. In 2026, use for type guards, dynamic dispatch, column validation in Dask/Polars/pandas, and integrate with dataclasses/Pydantic for runtime checks. Master isinstance(), and you’ll write flexible, type-safe, and inheritance-friendly code in any Python project.
Next time you need to check an object’s type — use isinstance(). It’s Python’s cleanest way to say: “Is this object what I expect — including subclasses?”