How to compare type of an object in Python?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Python provides several ways to check an object's type: type() returns the exact type, isinstance() checks against a type or tuple of types (including subclasses), and issubclass() checks class relationships without an instance. The key rule is to prefer isinstance() over type() comparisons in almost all cases because it respects inheritance and is the Pythonic convention.
type() — Exact Type Check
type() returns the exact class of an object:
type() does not consider inheritance. True is a bool, which is a subclass of int, but type(True) == int returns False because the exact type is bool, not int.
isinstance() — Preferred Approach
isinstance() checks whether an object is an instance of a class or any of its subclasses:
Use isinstance() when you want to accept any subclass of a type:
issubclass() — Class Relationship Check
issubclass() checks the relationship between two classes (not instances):
This is useful for type validation in class hierarchies:
type() is vs type() ==
Use is for type comparisons since built-in types are singletons. There is only one int type object in the interpreter.
Checking Against Multiple Types
isinstance() with a tuple is cleaner and handles subclasses correctly.
Type Checking with typing Module
For complex types (generics, unions), use the typing module with runtime checks:
For runtime validation of complex types, consider typeguard or beartype:
Duck Typing Alternative
Python's philosophy often favors duck typing — check capabilities rather than types:
Or use hasattr() and protocol checks:
class Attribute
Every object has a __class__ attribute that is equivalent to type():
__name__ is useful for logging or error messages where you need the type name as a string.
Common Pitfalls
- Using
type()whenisinstance()is correct:type(x) == SomeClassbreaks polymorphism. ADoginstance would fail atype(x) == Animalcheck. Always useisinstance()unless you explicitly need to exclude subclasses. - Comparing type() with a string:
type(x) == 'int'always returnsFalsebecausetype()returns a class object, not a string. Usetype(x).__name__ == 'int'if you must compare by name, but preferisinstance(x, int). - Forgetting
boolis a subclass ofint:isinstance(True, int)returnsTrue. If you need to distinguish booleans from integers, checkisinstance(x, bool)first sinceboolis more specific. - Not using a tuple with isinstance: Writing
isinstance(x, int) or isinstance(x, float)is verbose. Useisinstance(x, (int, float))instead. - Over-checking types in dynamic code: Python is dynamically typed by design. Excessive type checking makes code rigid and less reusable. Use type checks at boundaries (public API inputs) and duck typing internally.
Summary
- Use
isinstance(obj, Type)for most type checks — it respects inheritance and accepts tuples - Use
type(obj) is Typeonly when you need an exact type match, excluding subclasses - Use
issubclass(ClassA, ClassB)to check class relationships without an instance boolis a subclass ofint— checkisinstance(x, bool)beforeisinstance(x, int)if distinction matters- Prefer duck typing (checking capabilities) over explicit type checking when possible
- Use
type(obj).__name__when you need the type as a string for logging or error messages

