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.
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
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan