Python type() Function

Usage

The type() function in Python is a built-in function primarily used to determine the type of an object, but it can also be used to dynamically create new classes.

Syntax

The type() function can be used in two different ways.

To find out the type of an object:

type(object)

ParameterConditionDescription
objectRequiredAny object (number, string, list, custom object etc.)

– OR –

To create a new type (essentially, dynamically creating classes):

type(name, bases, dict)

ParameterConditionDescription
nameRequiredThe name of the new class
basesOptionalA tuple of base classes from which the new class will inherit.
dictOptionalA dictionary containing class attributes and methods

Determining the Type of an Object

When you use type() with a single argument, it returns the type object of that argument.

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">

Now, let’s test type() on a custom object:

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'>

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. You can do this by comparing the output of the type() function directly to the type object you’re interested in.

print(type(5) is int)         # Output: True
print(type(5) is float)       # Output: False
print(type("Hello") is str)   # Output: 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))  # Output: True
print(type(3.14) in (int, float))          # Output: True

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

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

Dynamically Creating Classes

Although not commonly used in everyday programming, using type() with three arguments allows you to create new classes on the fly.

This is a form of metaprogramming, allowing you to generate new classes during the execution of your program, rather than having them all rigidly defined beforehand.

Here’s how you can use type() in this manner:

Car = type("Car", (), {"wheels": 4,
                       "color": "Black",
                       "style": "Sedan",
                       "showDescription": lambda self: print("This is a", self.color, self.style)})

new_car = Car()
print(new_car.wheels)       # Output: "4"
print(new_car.style)        # Output: "Sedan"
new_car.showDescription()   # Output: "This is a Black Sedan"

In this example, a Car class is created dynamically. This class has attributes like wheels, color, and style. It also includes a method called showDescription to print information about the car. A new_car object is then instantiated from this class, and its attributes and methods are accessed.

type() vs isinstance()

While type() is used to determine the type of an object, Python also offers the isinstance() function to check if an object is an instance of a specific class or a tuple of classes. 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))   # Output: True
print(type(apple) is Apple)       # Output: True

print(isinstance(apple, Fruit))   # Output: True
print(type(apple) is Fruit)       # Output: 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))   # Output: True
print(type(True) is bool)       # Output: True

print(isinstance(True, int))    # Output: True
print(type(True) is int)        # Output: 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.