Support Online
Skip to main content

Python type() Function Explained

The type() function in Python actually performs two functions:

  1. Learning exactly which class an object belongs to,
  2. Creating new classes dynamically at runtime.

In this article, we will see the syntax of the type() function, its usage examples with ready-made and custom classes, its role in dynamic class creation, and the differences between it and isinstance().

The function has a very simple structure. Without further ado, let's look at the syntax.

Syntax of Python type() Function

There are many built-in functions in Python. One of these, type(), is used to find out the type of an object.

The syntax is as follows:

type(object)
type(name, bases, dict)

Given a single argument, the type() function returns the type of the object. This value is actually the same as the __class__ attribute of the object.

When given three arguments, it returns a new type (class). So you can create a dynamic class at runtime.

  • "name" (name) → It becomes the name of the class to be created. This corresponds to the __name__ attribute of the class.
  • "bases" → Specifies the classes that the class will inherit. This corresponds to the __bases__ attribute of the class.
  • "dictionary" (dict) → Defines the body of the class (methods and properties). This is the same as the __dict__ attribute of the class.

In short:

  • 1 argument → Type learning (object.__class__)
  • 3 arguments → Dynamic class creation (__name__, __bases__, __dict__)

Knowing this difference comes in handy both in day-to-day type checks and in more advanced dynamic programming. 🐍

Python type() Function Examples

Now let's look at some examples of using the type() function.

1. Finding the type of a Python object

x = 10
print(type(x))
# <class 'int'>

s = 'abc'
print(type(s))
# <class 'str'>

from collections import OrderedDict

od = OrderedDict()
print(type(od))
# <class 'collections.OrderedDict'>

class Veri:
pass

d = Veri()
print(type(d))
# <class '__main__.Veri'>
Output
<class 'int'>
<class 'str'>
<class 'collections.OrderedDict'>
<class 'main.Veri'>

Notice that the type() function returns the type of the object along with the module name.

Since the Python file we wrote is not a separate module, but a directly executed script, the module name automatically becomes __main__.

So when you define custom classes, it is normal to see __main__.<SınıfAdı> in the output.

2. Extracting Details from Python Classes

Let's say we have several classes. We can get some metadata from these classes. For this, the following attributes of classes are useful to us:

  • __class__ → The class to which the object belongs
  • __bases__ → Base classes from which the class inherits
  • __dict__ → Methods and properties of the class
  • __doc__ → Class documentation (docstring) text

Thanks to these attributes, we can examine the structure of the class more closely.

class Veri:
"""Veri Sınıfı"""
v_id = 10

class AltVeri(Veri):
"""AltVeri Sınıfı"""
av_id = 20

Let's print some properties of these classes on the screen.

print(Veri.__class__)
# <class 'type'>

print(Veri.__bases__)
# (<class 'object'>,)

print(Veri.__dict__)
# {'__module__': '__main__', 'v_id': 10, '__doc__': 'Veri Sınıfı', ...}

print(Veri.__doc__)
# Veri Sınıfı


print(AltVeri.__class__)
# <class 'type'>

print(AltVeri.__bases__)
# (<class '__main__.Veri'>,)

print(AltVeri.__dict__)
# {'__module__': '__main__', 'av_id': 20, '__doc__': 'AltVeri Sınıfı', ...}

print(AltVeri.__doc__)
# AltVeri Sınıfı
Output:
<class 'type'>
(<class 'object'>,)
{'module': 'main', 'doc': 'Veri Sınıfı', 'v_id': 10, 'dict': <attribute 'dict' of 'Veri' objects>, 'weakref': <attribute 'weakref' of 'Veri' objects>}
Veri Sınıfı

<class 'type'>
(<class 'main.Veri'>,)
{'module': 'main', 'doc': 'AltVeri Sınıfı', 'av_id': 20}
AltVeri Sınıfı

We can also create similar classes using the type() function.

Veri1 = type("Veri1", (object,), {"__doc__": "Veri1 Sınıfı", "v_id": 10})
AltVeri1 = type("AltVeri1", (Veri1,), {"__doc__": "AltVeri1 Sınıfı", "av_id": 20})

print(Veri1.__class__)
# <class 'type'>

print(Veri1.__bases__)
# (<class 'object'>,)

print(Veri1.__dict__)
# {'__module__': '__main__', '__doc__': 'Veri1 Sınıfı', 'v_id': 10, ...}

print(Veri1.__doc__)
# Veri1 Sınıfı


print(AltVeri1.__class__)
# <class 'type'>

print(AltVeri1.__bases__)
# (<class '__main__.Veri1'>,)

print(AltVeri1.__dict__)
# {'__module__': '__main__', '__doc__': 'AltVeri1 Sınıfı', 'av_id': 20, ...}

print(AltVeri1.__doc__)
# AltVeri1 Sınıfı
Output:
<class 'type'>
(<class 'object'>,)
{'doc': 'Veri1 Sınıfı', 'v_id': 10, 'module': 'main', 'dict': <attribute 'dict' of 'Veri1' objects>, 'weakref': <attribute 'weakref' of 'Veri1' objects>}
Veri1 Sınıfı

<class 'type'>
(<class 'main.Veri1'>,)
{'doc': 'AltVeri1 Sınıfı', 'av_id': 20, 'module': 'main'}
AltVeri1 Sınıfı

Remember, we can also add functions (methods) to the dynamic classes we create using the type() function.

Real-Life Use of the type() Function

Since Python is a dynamically-typed language, you can use the type() function when you want to find out the type of a variable.

If you want a function to work only on certain types, the isinstance() function would be the better choice.

For example, let's say we want to write a function that operates on two integers. We can implement this like this:

def hesapla(x, y, op='topla'):
if not(isinstance(x, int) and isinstance(y, int)):
print(f'Hatalı Argüman Tipi - x:{type(x)}, y:{type(y)}')
raise TypeError('Uygun olmayan tip, sadece tam sayı (int) olmalı')

if op == 'fark':
return x - y
if op == 'carp':
return x * y
# varsayılan işlem toplama
return x + y

The isinstance() function is used to verify the type of arguments entered.

If the type check fails, we can print on the screen the type of the parameters with the type() function.

So in summary:

  • isinstance() → For verification
  • type() → To show type on error

Checking Variable Types Correctly

While type() is useful for finding out the exact type of an object, it is not always the best option for conditional checks. Especially when inheritance comes into play.

  • type(obj) == SomeClass
    This check returns True if obj derives exactly from class SomeClass.
    If obj comes from a subclass of SomeClass, it returns False.

  • isinstance(obj, SomeClass)
    This check checks whether obj is both from the SomeClass class and one of its subclasses.
    In other words, it is a more flexible method and is more compatible with polymorphism logic.

In short:

  • Precise class controltype()
  • Flexible and legacy-friendly controlisinstance()

Best Usage Tips for type() vs isinstance()

  • Type Validation in Functions / Methods
    If you want to accept a specific type or its subclasses, use isinstance(). This approach makes its functions more flexible and durable.

  • Exact Type Identification
    If you want to find out exactly which class an object belongs to and distinguish between base classes and subclasses, use type().
    This is generally not required in daily applications, but it can be useful when developing a framework or in very special scenarios.

  • Debugging and Logging
    type() is perfect if you need to press the screen to determine the type of object. It helps you quickly understand the nature of the object while debugging or logging.


Result

The type() function in Python is a very important tool in advanced scenarios such as understanding the exact structure of objects and creating dynamic classes.

  • Single argument version → Learning the exact class of the object is very useful for debugging and introspection.
  • Three-argument version → Provides powerful metaprogramming opportunities thanks to dynamic class creation.

However, when doing type checking in application logic, especially when it comes to inheritance, it is recommended that developers use isinstance() more. In this way, the code becomes both more flexible and suitable for polymorphism.

For more Python topics, you can also check out our article: