Check an object’s type in Python

Choose isinstance for subclass-aware checks, type for exact matches, and behavior-based interfaces when a concrete class is unnecessary.

Best practices
Python programming and application logging

Use isinstance(obj, SomeClass) when subclasses should also be accepted. Use type(obj) is SomeClass when the exact runtime type matters. If the function only needs an operation such as iteration, accepting that behavior can be more flexible than requiring one concrete container type.

Require an exact type

value = 5
print(type(value))       # <class 'int'>
print(type(value) is int)  # True
print(type(True) is int)   # False

An exact check intentionally excludes subclasses. This can be useful at a strict boundary, but is often too restrictive for extensible application code.

Accept subclasses

class A:
    pass

class B(A):
    pass

print(isinstance(B(), A))          # True
print(isinstance(True, int))       # True
print(isinstance(3.5, (int, float))) # True

bool is a subclass of int. If a numeric input must exclude booleans, include that requirement explicitly, for example isinstance(value, int) and not isinstance(value, bool).

Ask for the behavior you use

def total_length(parts):
    return sum(len(part) for part in parts)

This function needs an iterable whose members support len; it does not require parts to be a list. Document that contract and let meaningful failures propagate, or validate it at the application boundary.

An attribute-existence check such as hasattr(obj, "read") does not prove that the attribute is callable or behaves as a file reader. Catching AttributeError around an entire method call can also hide an AttributeError raised inside the method. Keep exception handling narrow and distinguish missing interface from implementation failure.

Use abstract interfaces where appropriate

from collections.abc import Mapping

print(isinstance({"a": 1}, Mapping))  # True

Abstract base classes can recognize subclasses and registered virtual subclasses. They are useful interface categories, but not every object that happens to expose similar methods is automatically recognized by every ABC. Registration itself does not validate an implementation's correctness.

FAQ

How should I check for None? Use value is None. It expresses identity with the singleton directly; a performance claim is unnecessary.

Does isinstance always mean ordinary inheritance? No. Abstract base classes and metaclasses can customize instance checks. For the exact runtime type, use type.

Is duck typing always better? No. Use the narrowest contract the task needs. Strict serialization or validation boundaries may need explicit types, while reusable processing functions often benefit from accepting compatible behavior.

References

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting