Check Type in Python

Learn how to check the type of a variable in Python using type() and isinstance(). See when to use each method, how to check multiple types, and how type hints differ from runtime type checking.

Published

Updated

Read time 8 min read

Reviewed byDeepak Prasad

Check Type in Python

Python is dynamically typed: a variable can hold different kinds of values during a program's run, and you do not declare a fixed type when you assign it.

To check type in Python at runtime, use type() or isinstance(). Use type(x) to see the exact type of a variable. Use isinstance(x, int) when you want to check whether a variable is an instance of a type or subclass. Python's official docs define isinstance() as returning True when an object is an instance of a class, subclass, tuple of classes, or union type.

Type hints are different: they help editors and tools such as mypy analyze code, but Python does not enforce them automatically at runtime.

Tested on: Python 3.13.3; kernel 6.14.0-37-generic.


Python check type quick reference

Task Use
Print the exact type of a variable type(variable)
Check if a value is an int isinstance(value, int)
Check if a value is a string isinstance(value, str)
Check multiple possible types isinstance(value, (int, float))
Check exact type only type(value) is int
Check class or subclass isinstance(obj, ClassName)
Check if a class is a subclass issubclass(Child, Parent)
Add static type information type hints
Run static type checking mypy or another type checker

Check the type of a variable using type()

The built-in type() function returns the type object for any value. It is useful for debugging and quick inspection.

python
x = 42
print(type(x))
print(type("hello"))
print(type([1, 2, 3]))
print(type({"a": 1}))
print(type((1, 2)))
print(type(True))
Output

Each line prints a <class '…'> line for int, str, list, dict, tuple, and bool respectively.

Use type() when you want to know exactly what Python sees at runtime—for example, while debugging unexpected data in a variable.

To require an exact type (not a subclass), compare with is:

python
values = [10, True, 3.14]

for value in values:
    if type(value) is int:
        print(f"{value!r} is exactly int")
    else:
        print(f"{value!r} is not exactly int")
Output

Only 10 is reported as exactly int. True is not, even though it behaves like 1 in many contexts—more on that in the common types section below.


Check if a variable is a specific type using isinstance()

isinstance() returns True or False. It is usually the better choice for real type checks inside if statements because it understands inheritance and accepts a tuple of types.

python
name = "Alice"
count = 7
items = [1, 2, 3]

print(isinstance(name, str))
print(isinstance(count, int))
print(isinstance(items, list))
print(isinstance(items, (list, tuple)))
Output

All four checks print True.

Check if a value is a string

python
def greet(value):
    if isinstance(value, str):
        return f"Hello, {value}"
    return "Expected a string"

print(greet("Sam"))
print(greet(42))
Output

The first call returns a greeting; the second returns "Expected a string".

Check if a value is a number

python
def double_if_number(value):
    if isinstance(value, (int, float)):
        return value * 2
    return None

print(double_if_number(5))
print(double_if_number(2.5))
print(double_if_number("5"))
Output

You get 10, 5.0, and None for integer, float, and non-numeric input.

Check if data is a list or tuple

python
def first_item(data):
    if isinstance(data, (list, tuple)):
        return data[0]
    raise TypeError("Expected a list or tuple")

print(first_item([10, 20, 30]))
print(first_item((1, 2, 3)))
Output

Both calls return 10 and 1.

Inheritance-aware checks

isinstance() follows the class hierarchy:

python
class Vehicle:
    pass

class Car(Vehicle):
    pass

my_car = Car()

print(isinstance(my_car, Car))
print(isinstance(my_car, Vehicle))
print(type(my_car) is Vehicle)
Output

The first two lines print True; the third prints False. isinstance(my_car, Vehicle) is True because Car is a subclass of Vehicle, but type(my_car) is Vehicle is False because the exact type is Car.


type() vs isinstance()

Feature type() isinstance()
Returns Type object True or False
Checks exact type Yes No; includes subclasses
Good for debugging Yes Sometimes
Good for conditional checks Sometimes Yes
Supports multiple types directly No Yes, with a tuple
Handles inheritance No Yes

Recommendation: use type() when you want to inspect the exact type. Use isinstance() when you want to check whether a value can be treated as a certain type—especially in functions that accept flexible input.


Check multiple types in Python

Pass a tuple as the second argument to isinstance():

python
def normalize_length(value):
    if isinstance(value, (str, list, tuple)):
        return len(value)
    raise TypeError("Expected str, list, or tuple")

print(normalize_length("hello"))
print(normalize_length([1, 2, 3, 4]))
Output

The function returns 5 for the string and 4 for the list.

This pattern is common when a function accepts more than one type—for example, numbers (int and float), sequences (list and tuple), or string-or-list inputs.


Check common Python data types

Data type Check
String isinstance(x, str)
Integer isinstance(x, int)
Float isinstance(x, float)
List isinstance(x, list)
Tuple isinstance(x, tuple)
Dictionary isinstance(x, dict)
Set isinstance(x, set)
Boolean isinstance(x, bool)
None x is None

Quick examples:

python
samples = {
    "text": "go",
    "number": 99,
    "ratio": 0.5,
    "items": [1, 2],
    "pair": (1, 2),
    "mapping": {"k": "v"},
    "unique": {1, 2},
    "flag": False,
    "empty": None,
}

checks = [
    ("text", isinstance(samples["text"], str)),
    ("number", isinstance(samples["number"], int)),
    ("ratio", isinstance(samples["ratio"], float)),
    ("items", isinstance(samples["items"], list)),
    ("pair", isinstance(samples["pair"], tuple)),
    ("mapping", isinstance(samples["mapping"], dict)),
    ("unique", isinstance(samples["unique"], set)),
    ("flag", isinstance(samples["flag"], bool)),
    ("empty", samples["empty"] is None),
]

for name, result in checks:
    print(f"{name}: {result}")
Output

Every check prints True.

Important: bool is a subclass of int in Python, so isinstance(True, int) returns True. If you need to distinguish booleans from integers, check bool first or use type(x) is bool:

python
print(isinstance(True, int))
print(isinstance(True, bool))
print(type(True) is int)
Output

The first two lines print True; the third prints False.


Check for None in Python

Use identity comparison:

python
value = None

if value is None:
    print("value is None")
Output

Do not use:

  • type(x) is Nonetype(None) is <class 'NoneType'>, not None
  • isinstance(x, None)None is not a valid class for isinstance()

For optional values, x is None and x is not None are the standard patterns.


Check custom class type

For your own classes, isinstance() works with parent and child classes:

python
class Animal:
    pass

class Dog(Animal):
    pass

pet = Dog()

print(isinstance(pet, Dog))
print(isinstance(pet, Animal))
print(type(pet) is Animal)
Output

The first two lines print True; the third prints False. Use type(obj) is ClassName only when you specifically want to reject subclasses and match the exact class.

To check relationships between classes themselves, use issubclass():

python
print(issubclass(Dog, Animal))
print(issubclass(Animal, Dog))
Output

The first line prints True; the second prints False.


Check if an object is callable

When you only need to know whether something can be called, use callable():

python
print(callable(print))
print(callable(len))
print(callable(42))
print(callable(lambda x: x * 2))
Output

print, len, and the lambda return True; the integer 42 returns False.

Do not overuse exact type checks to detect functions. In Python, behavior often matters more than the exact class name.


Runtime type checking vs static type checking

Approach When it runs Examples
Runtime checks While the program executes type(), isinstance(), callable()
Static checks Before or during development type hints analyzed by mypy, Pyright, or your IDE

type() and isinstance() inspect live objects. Type hints are annotations for developers and tools—they do not stop Python from running code with mismatched values unless you add explicit runtime checks yourself.

Install and run mypy on a file when you want static analysis:

text
pip install mypy
mypy script.py

This is not a full mypy tutorial; the key point is that static checkers complement—not replace—runtime checks.


Type hints in Python

Type hints document expected types without enforcing them at runtime:

python
def add(x: int, y: int) -> int:
    return x + y

name: str = "Alice"
scores: list[int] = [90, 85, 88]
profile: dict[str, int] = {"age": 30}
label: str | None = None
Output

Modern Python uses built-in generics such as list[int] and union syntax such as str | None (Python 3.10+). These help readability and static tools; they are not a substitute for isinstance() when you need runtime validation of user input.

For return types and more complex signatures, annotations follow the same idea: document intent, then let a type checker verify consistency before runtime.


When not to check types

Python often prefers duck typing: if an object behaves the way you need, its exact type may not matter.

Alternatives to heavy type checking:

  • Use try / except when converting input instead of long isinstance() chains.
  • Use callable() when you need something invokable.
  • Use hasattr() carefully when probing for capabilities—prefer well-defined interfaces when possible.

Example with conversion instead of pre-checking every type:

python
def to_int(value):
    try:
        return int(value)
    except (TypeError, ValueError):
        return None

print(to_int("42"))
print(to_int("abc"))
Output

to_int("42") returns 42; invalid input returns None.

Flexible code that handles behavior gracefully is often more Pythonic than strict type gates everywhere.


Summary

Use type(x) to inspect the exact type of a variable at runtime. For most practical checks in conditions, prefer isinstance(x, SomeType), and pass a tuple such as (int, float) when more than one type is valid. Test for None with x is None, not with type(). Type hints and tools like mypy help during development but do not enforce types when the program runs. When strict type gates add noise without real safety, lean on duck typing, callable(), or try / except instead.

Useful references


Frequently Asked Questions

1. How do I check the type of a variable in Python?

Use type(variable) to see the exact type, or isinstance(variable, int) (or str, list, and so on) when you need a True/False check in a condition. For most runtime checks, isinstance() is the better choice.

2. What is the difference between type() and isinstance() in Python?

type(x) returns the exact type object. isinstance(x, SomeType) returns True when x is an instance of SomeType or a subclass. Use type() for debugging; use isinstance() for conditional checks and inheritance-aware code.

3. How do I check if a variable is a string or number in Python?

Use isinstance(x, str) for strings and isinstance(x, (int, float)) when a value may be either integer or float. Remember that bool is a subclass of int, so isinstance(True, int) is True.

4. How do I check for None in Python?

Use x is None. Do not use type(x) is None or isinstance(x, None). Identity comparison with is None is the standard Python pattern.

5. Does Python enforce type hints at runtime?

No. Type hints are annotations for developers and static tools such as mypy. They do not change runtime behavior unless you add your own checks. Use type() and isinstance() for runtime type checking.

6. When should I use callable() instead of a type check?

Use callable(obj) when you only need to know whether something can be called like a function. Checking exact types is often unnecessary when behavior matters more than the class name.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …