Determine the type of an object?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In Python, the two most common tools for determining an object's type are type() and isinstance(). They are related, but they answer slightly different questions.
If you only remember one rule, remember this: use isinstance() when you want to know whether an object behaves as a member of a class hierarchy, and use type() when you need the exact runtime type.
Using type()
type(obj) returns the actual runtime class of the object:
That prints something like:
This is useful for debugging, logging, introspection, and cases where you truly need to compare exact types.
For example:
That test succeeds only when the object's concrete type is exactly float.
Using isinstance()
isinstance(obj, cls) answers a broader question: is this object an instance of the given class or any subclass of it?
Both lines print True.
That is why isinstance() is usually better for application logic. It respects inheritance and is more aligned with normal object-oriented design.
Why isinstance() Is Usually Preferred
Suppose you have code that should accept any list-like subclass you defined yourself. If you use type(obj) is list, subclasses fail the test even if they behave correctly.
The first line is False, while the second is True.
That is usually what you want. If a subclass is valid for your logic, isinstance() expresses the intent more accurately.
Checking Multiple Possible Types
isinstance() can also accept a tuple of classes:
This is cleaner than chaining several separate comparisons.
When Exact Type Comparison Is Correct
There are still cases where type() is the right tool. If your logic truly depends on the exact implementation class and should reject subclasses, then exact type comparison is appropriate.
This is an important example because bool is a subclass of int in Python. So isinstance(True, int) is True, which surprises many developers. If you need to distinguish booleans from integers precisely, type() is the safer check.
Type Checks Versus Duck Typing
Python often encourages duck typing: instead of asking what type an object is, ask whether it supports the operation you need.
For example, instead of checking whether something is a list, you might simply try iterating over it:
That function works for lists, tuples, generators, and many custom iterable objects without caring about their exact type.
So even though type() and isinstance() are useful, do not reach for them automatically if a capability-based design is simpler.
Common Pitfalls
The biggest pitfall is using type(obj) is SomeClass when subclasses should also count. That usually makes the code more brittle than necessary.
Another common issue is forgetting Python's inheritance quirks, especially that bool is a subclass of int. That can produce surprising results if you assume integers and booleans are completely separate.
Developers also overuse type checks when duck typing would be cleaner. If your real requirement is "can I iterate over this" or "does this object have a .read() method," checking exact types may be the wrong abstraction.
Finally, avoid comparing type names as strings. Use the class objects themselves rather than expressions like type(obj).__name__ == "int" unless you are formatting output for humans.
Summary
- Use
type(obj)when you need the exact runtime type. - Use
isinstance(obj, cls)when subclasses should also count. - '
isinstance()is usually better for normal application logic.' - '
type()is useful for debugging and for cases where exact type identity matters.' - In Python, consider duck typing before adding explicit type checks at all.

