How to Get and Check the Type of an Object in Python

Python’s dynamic typing offers great flexibility, allowing variables to hold values of different types throughout your code. However, this flexibility also means you need to be mindful of the types you’re working with to write robust and error-free programs.

This article covers how to get and check the type of an object in Python, including examples and best practices. Let’s get started!

Getting the Type of an Object

Using the type() Function

To get the type of an object in Python, you use the built-in function type(). This function returns the type object of the argument passed to it. Let’s see some examples:

print(type(42))
# Output: <class "int">

print(type(3.14))
# Output: <class 'float'>

print(type("Hello"))
# Output: <class "str">

print(type(False))
# Output: <class 'bool'>

print(type(["red", "green", "blue"]))
# Output: <class "list">

print(type({"name": "Bob", "age": 25}))
# Output: <class "dict">

The type() function works not just with built-in types but also objects of custom classes.

class fruit:
  pass

apple = fruit()
print(type(apple))
# Output: <class '__main__.fruit'>

Notice the __main__ before the class name. This indicates that the Fruit class is local to the current module.

You can even use type() on special objects like functions and modules:

# Functions
def greet(name):
    print("Hello,", name)
print(type(greet))    # Output: <class 'function'>

# Modules
import math
print(type(math))     # Output: <class 'module'>

Using the __class__ attribute

Objects in Python have a built-in attribute called __class__ that stores a reference to the class from which they were created. You can access this attribute to get an object’s type:

print((42).__class__)
# Output: <class "int">

print((3.14).__class__)
# Output: <class 'float'>

print("Hello".__class__)
# Output: <class "str">

While this works, the type() function is generally preferred for its clarity and readability.

Checking the Type of an Object

Once you’ve obtained the type, you might want to check if an object is of a certain type. There are two primary ways to do this:

Using the type() Function

To check the type of an object, you can compare the output of the type() function directly to the type you’re interested in.

print(type(5) is int)         # True
print(type(5) is float)       # False
print(type("Hello") is str)   # True

To check if the type of an object is among multiple possible types, use the in operator with a tuple of potential types:

print(type("Hello") in (int, float, str))  # True
print(type(3.14) in (int, float))          # True

To reverse the logic of your type checks, use the not operator:

print(type(3.14) is not int)  # True
print(type([1, 2, 3]) not in (int, float, str))  # True

Using the isinstance() Function

Another way to check an object’s type is to use the isinstance() function. It checks if an object is an instance of a particular class or any subclass derived from it.

print(isinstance(42, int))          # True (42 is an integer)
print(isinstance("Hello", str))     # True ("Hello" is a string)
print(isinstance([1, 2, 3], list))  # True ([1, 2, 3] is a list)

print(isinstance(15, float))        # False (15 is not a float)
print(isinstance("World", list))    # False ("World" is not a list)

You can even use isinstance() with custom classes:

class Car():
    pass

my_car = Car()
print(isinstance(my_car, Car))    # True

You can pass a tuple to isinstance() to check if the object is an instance of any of the classes or types in that tuple:

print(isinstance(42, (int, float)))       # True (42 is an integer)
print(isinstance(3.14, (int, float)))     # True (3.14 is a float)

print(isinstance("Hello", (int, float)))  # False ("Hello" is neither)

type() vs isinstance()

While both type() and isinstance() functions are used to check the type of an object, the difference between them is subtle but important:

The type() function focuses on the exact type of an object. It will only return True if the object’s type directly matches the class you’re comparing against, ignoring inheritance.

On the other hand, isinstance() takes inheritance into account. It checks if an object is an instance of a particular class or any of its subclasses. This means if an object belongs to a derived class (a subclass), isinstance() will still recognize it as being an instance of the parent class.

Let’s illustrate this with an example:

class Fruit:
    pass

class Apple(Fruit):
    pass

apple = Apple()

print(isinstance(apple, Apple))   # True
print(type(apple) is Apple)       # True

print(isinstance(apple, Fruit))   # True
print(type(apple) is Fruit)       # False (probably won't be what you want)

Another interesting example is that booleans (True and False) in Python are a subclass of integers. Therefore, a boolean object will return True when checked with isinstance() against both the bool and int types. However, because type() does not consider class inheritance, the check will return False for int.

print(isinstance(True, bool))   # True
print(type(True) is bool)       # True

print(isinstance(True, int))    # True
print(type(True) is int)        # False

Therefore, for most common programming scenarios, isinstance() is the preferred choice. This is because it aligns well with object-oriented programming principles where you often want to treat objects of subclasses as if they belong to the parent class itself. You usually would want to be able to use an Apple object in any place where the code expects a Fruit. However, there might be specific situations where you need to strictly identify an object’s exact type without considering inheritance. In these rarer cases, type() is the right tool.