How to Create Custom Data Types in Python

Learn how to build custom data types in Python using classes, dataclasses, and enums with practical examples.
E
AuthorEditorial Team
Last Commit2026-08-01

When you first learn Python, you use the basic built-in data types. You use str for text, int for whole numbers, and list to hold multiple items. These basic types are great for simple programs.

But as your programs grow larger, you will need to group different pieces of information together.

To make your code safer and easier to read, you can create your own custom data types. By doing this, you tell Python exactly what information is allowed and how it should behave.

When to Use Custom Types

You do not always need custom data types. Knowing when to use the built-in types (like lists and dictionaries) saves you a lot of time.

Use Built-in Data Types When:

  • You are writing a quick, short script.
  • The data is simple and temporary.
  • Example: If you just need to read a text file and count how many times the word "Python" appears, you only need built-in strings (str) and numbers (int).

Use Custom Data Types When:

  • You are building a large application that you will maintain for a long time.
  • Specific pieces of data always travel together.
  • The data has strict rules.
  • Example: If you are building an email application, you should create a custom Email data type. An email must always have a sender, a receiver, a subject line, and a true/false value showing if it has been read. If you just use a dictionary, another programmer might forget to include the "sender" information, which would break the application. A custom type prevents this mistake.

Here are three ways to create custom data types in Python, starting with the most common way.

1. Using Standard Classes (For Data and Actions)

In Python, the most common way to create a custom data type is by using a class.

You can think of a class as a strict blueprint. It tells Python exactly what pieces of information belong together. It also lets you create actions that the data can perform.

2. Using Data Classes (For Just Holding Information)

Writing the setup function (the __init__ part in the code above) can take a lot of time if you have 10 or 20 pieces of information to store.

If you want to create a custom data type that only holds information and does not need to perform actions, you should use a Data Class. Python added Data Classes to write all the repetitive setup code for you behind the scenes.

3. Using Enums (For a Strict List of Choices)

Sometimes, a piece of data should only be allowed to be one of a few exact choices.

For example, an order status in a store application should only be "Pending", "Shipped", or "Delivered". If you use regular text strings for this, someone might accidentally type "Shiped" with one "p".

To prevent these spelling mistakes, you can use an Enum. This simply means a numbered list of specific choices.

Summary

Here is a simple guide to help you choose which method to use:

What do you need your custom data type to do?What should you use?
It needs to hold information and perform specific actions.Use a standard class.
It only needs to hold information.Use a @dataclass.
It needs to restrict information to a specific list of choices.Use an Enum.

FAQs

?Why do I have to write "self" so many times in standard classes?↓
This is the most common question beginners ask. The word "self" is how Python knows exactly which piece of data it is working with. Imagine you have two players in a game: Player A and Player B. If Player A takes damage, Python needs a way to know it should lower Player A's health, not Player B's health. The word "self" simply means "the specific player we are looking at right now."
?Can I put a custom data type inside another custom data type?↓
Yes. This is actually the best way to write code for large applications. You can use an "Enum" as one of the variables inside your dataclass. # Here is a quick example of mixing custom types: from dataclasses import dataclass from enum import Enum class OrderStatus(Enum): PENDING = 1 SHIPPED = 2 @dataclass class StoreOrder: order_number: int # We use our custom Enum type as a variable inside our Data Class status: OrderStatus # Creating the order my_order = StoreOrder(order_number=9945, status=OrderStatus.PENDING)
?Should I stop using dictionaries completely?↓
No, you should still use dictionaries. Dictionaries are the best choice when you do not know exactly what the data will look like ahead of time. For example, if you are downloading a list of information from a random website, you should put it in a dictionary first. Use custom data types only when you know the exact, permanent structure your data needs to have.
?Do custom data types slow down my program?↓
No. In fact, using modern tools like @dataclass can sometimes make your code run slightly faster and use less memory than large, messy dictionaries. More importantly, custom data types save you time by preventing bugs and stopping you from making spelling mistakes in your code.

ls ./related-articles