Data classes are just regular classes that are geared towards storing state, rather than containing a lot of logic. Every time you create a class that mostly consists of attributes, you make a data class.

What the dataclasses module does is to make it easier to create data classes. It takes care of a lot of boilerplate for you.

This is especially useful when your data class must be hashable; because this requires a __hash__ method as well as an __eq__ method. If you add a custom __repr__ method for ease of debugging, that can become quite verbose:

class InventoryItem:
    '''Class for keeping track of an item in inventory.'''
    name: str
    unit_price: float
    quantity_on_hand: int = 0

    def __init__(
            self, 
            name: str, 
            unit_price: float,
            quantity_on_hand: int = 0
        ) -> None:
        self.name = name
        self.unit_price = unit_price
        self.quantity_on_hand = quantity_on_hand

    def total_cost(self) -> float:
        return self.unit_price * self.quantity_on_hand
    
    def __repr__(self) -> str:
        return (
            'InventoryItem('
            f'name={self.name!r}, unit_price={self.unit_price!r}, '
            f'quantity_on_hand={self.quantity_on_hand!r})'
        )

    def __hash__(self) -> int:
        return hash((self.name, self.unit_price, self.quantity_on_hand))

    def __eq__(self, other) -> bool:
        if not isinstance(other, InventoryItem):
            return NotImplemented
        return (
            (self.name, self.unit_price, self.quantity_on_hand) == 
            (other.name, other.unit_price, other.quantity_on_hand))

With dataclasses you can reduce it to:

from dataclasses import dataclass

@dataclass(unsafe_hash=True)
class InventoryItem:
    '''Class for keeping track of an item in inventory.'''
    name: str
    unit_price: float
    quantity_on_hand: int = 0

    def total_cost(self) -> float:
        return self.unit_price * self.quantity_on_hand

(Example based on the PEP example).

The same class decorator can also generate comparison methods (__lt__, __gt__, etc.) and handle immutability.

namedtuple classes are also data classes, but are immutable by default (as well as being sequences). dataclasses are much more flexible in this regard, and can easily be structured such that they can fill the same role as a namedtuple class.

The PEP was inspired by the attrs project, which can do even more (including slots, validators, converters, metadata, etc.).

If you want to see some examples, I recently used dataclasses for several of my Advent of Code solutions, see the solutions for day 7, day 8, day 11 and day 20.

If you want to use dataclasses module in Python versions < 3.7, then you could install the backported module (requires 3.6) or use the attrs project mentioned above.

Answer from Martijn Pieters on Stack Overflow
🌐
Python
docs.python.org › 3 › library › dataclasses.html
dataclasses — Data Classes
This function is not strictly required, because any Python mechanism for creating a new class with __annotations__ can then apply the @dataclass function to convert that class to a dataclass. This function is provided as a convenience. For example:
🌐
Real Python
realpython.com › python-data-classes
Data Classes in Python (Guide) – Real Python
March 18, 2026 - Data classes do not implement a .__str__() method, so Python will fall back to the .__repr__() method. Let us implement a user-friendly representation of a PlayingCard: ... from dataclasses import dataclass @dataclass class PlayingCard: rank: str suit: str def __str__(self): return f'{self.suit}{self.rank}'
Discussions

python - What are data classes and how are they different from common classes? - Stack Overflow
If you want to see some examples, I recently used dataclasses for several of my Advent of Code solutions, see the solutions for day 7, day 8, day 11 and day 20. If you want to use dataclasses module in Python versions < 3.7, then you could install the backported module (requires 3.6) or use ... More on stackoverflow.com
🌐 stackoverflow.com
python - Dataclasses and property decorator - Stack Overflow
I've been reading up on Python 3.7's dataclass as an alternative to namedtuples (what I typically use when having to group data in a structure). I was wondering if dataclass is compatible with the property decorator to define getter and setter functions for the data elements of the dataclass. If so, is this described somewhere? Or are there examples ... More on stackoverflow.com
🌐 stackoverflow.com
Why you should use Data Classes in Python
Neato! As a python noob, I had never heard of dataclasses until today and I'll definitely keep this in mind for the future. More on reddit.com
🌐 r/Python
74
611
September 16, 2022
Any reason not to use dataclasses everywhere?
When I don't control the storage or need primitive types for any reason, I use named tuples. They're also great More on reddit.com
🌐 r/Python
70
44
October 24, 2022
🌐
Reddit
reddit.com › r/learnpython › dataclass - what is it [for]?
r/learnpython on Reddit: Dataclass - what is it [for]?
May 22, 2025 -

I've been learning OOP but the dataclass decorator's use case sort of escapes me.

I understand classes and methods superficially but I quite don't understand how it differs from just creating a regular class. What's the advantage of using a dataclass?

How does it work and what is it for? (ELI5, please!)


My use case would be a collection of constants. I was wondering if I should be using dataclasses...

class MyCreatures:
        T_REX_CALLNAME = "t-rex"
        T_REX_RESPONSE = "The awesome king of Dinosaurs!"
        PTERODACTYL_CALLNAME = "pterodactyl"
        PTERODACTYL_RESPONSE = "The flying Menace!"
        ...

 def check_dino():
        name = input("Please give a dinosaur: ")
        if name == MyCreature.T_REX_CALLNAME:
                print(MyCreatures.T_REX_RESPONSE)
        if name = ...

Halp?

🌐
GeeksforGeeks
geeksforgeeks.org › python › understanding-python-dataclasses
Understanding Python Dataclasses - GeeksforGeeks
2 weeks ago - The dataclasses module in Python helps define classes that mainly store data. Introduced in Python 3.7, it can automatically generate methods such as __init__(), __repr__(), and __eq__(), reducing the code required for data-oriented classes. For example:
🌐
Hamy
hamy.xyz › blog › 2023-10-python-dataclasses
Python Dataclass best practices (and why you should use them) - HAMY
""" Example 1: Simple dataclasses * Temperature, Unit pairs """ print("Example 1: Simple dataclasses") class TemperatureUnit(Enum): CELSIUS = 1 FARENHEIGHT = 2 @dataclass class Temperature: TemperatureMagnitude: float Unit: TemperatureUnit temperature_tuple = (50.0, TemperatureUnit.CELSIUS) ...
🌐
Molssi
education.molssi.org › type-hints-pydantic-tutorial › chapters › DataclassInPython.html
Dataclasses In Python — Python Type Hints, Dataclasses, and Pydantic
The dataclass decorator reads the class attributes and assigns those attributes variables of the same name on calling the class, taking the same argument order as the attribute appears. In practice, you mainly just have to take your variable arguments and turn them into class attributes; type ...
Find elsewhere
Top answer
1 of 5
542

Data classes are just regular classes that are geared towards storing state, rather than containing a lot of logic. Every time you create a class that mostly consists of attributes, you make a data class.

What the dataclasses module does is to make it easier to create data classes. It takes care of a lot of boilerplate for you.

This is especially useful when your data class must be hashable; because this requires a __hash__ method as well as an __eq__ method. If you add a custom __repr__ method for ease of debugging, that can become quite verbose:

class InventoryItem:
    '''Class for keeping track of an item in inventory.'''
    name: str
    unit_price: float
    quantity_on_hand: int = 0

    def __init__(
            self, 
            name: str, 
            unit_price: float,
            quantity_on_hand: int = 0
        ) -> None:
        self.name = name
        self.unit_price = unit_price
        self.quantity_on_hand = quantity_on_hand

    def total_cost(self) -> float:
        return self.unit_price * self.quantity_on_hand
    
    def __repr__(self) -> str:
        return (
            'InventoryItem('
            f'name={self.name!r}, unit_price={self.unit_price!r}, '
            f'quantity_on_hand={self.quantity_on_hand!r})'
        )

    def __hash__(self) -> int:
        return hash((self.name, self.unit_price, self.quantity_on_hand))

    def __eq__(self, other) -> bool:
        if not isinstance(other, InventoryItem):
            return NotImplemented
        return (
            (self.name, self.unit_price, self.quantity_on_hand) == 
            (other.name, other.unit_price, other.quantity_on_hand))

With dataclasses you can reduce it to:

from dataclasses import dataclass

@dataclass(unsafe_hash=True)
class InventoryItem:
    '''Class for keeping track of an item in inventory.'''
    name: str
    unit_price: float
    quantity_on_hand: int = 0

    def total_cost(self) -> float:
        return self.unit_price * self.quantity_on_hand

(Example based on the PEP example).

The same class decorator can also generate comparison methods (__lt__, __gt__, etc.) and handle immutability.

namedtuple classes are also data classes, but are immutable by default (as well as being sequences). dataclasses are much more flexible in this regard, and can easily be structured such that they can fill the same role as a namedtuple class.

The PEP was inspired by the attrs project, which can do even more (including slots, validators, converters, metadata, etc.).

If you want to see some examples, I recently used dataclasses for several of my Advent of Code solutions, see the solutions for day 7, day 8, day 11 and day 20.

If you want to use dataclasses module in Python versions < 3.7, then you could install the backported module (requires 3.6) or use the attrs project mentioned above.

2 of 5
278

Overview

The question has been addressed. However, this answer adds some practical examples to aid in the basic understanding of dataclasses.

What exactly are python data classes and when is it best to use them?

  1. code generators: generate boilerplate code; you can choose to implement special methods in a regular class or have a dataclass implement them automatically.
  2. data containers: structures that hold data (e.g. tuples and dicts), often with dotted, attribute access such as classes, namedtuple and others.

"mutable namedtuples with default[s]"

Here is what the latter phrase means:

  • mutable: by default, dataclass attributes can be reassigned. You can optionally make them immutable (see Examples below).
  • namedtuple: you have dotted, attribute access like a namedtuple or a regular class.
  • default: you can assign default values to attributes.

Compared to common classes, you primarily save on typing boilerplate code.


Features

This is an overview of dataclass features (TL;DR? See the Summary Table in the next section).

What you get

Here are features you get by default from dataclasses.

Attributes + Representation + Comparison

import dataclasses


@dataclasses.dataclass
#@dataclasses.dataclass()                                       # alternative
class Color:
    r : int = 0
    g : int = 0
    b : int = 0

These defaults are provided by automatically setting the following keywords to True:

@dataclasses.dataclass(init=True, repr=True, eq=True)

What you can turn on

Additional features are available if the appropriate keywords are set to True.

Order

@dataclasses.dataclass(order=True)
class Color:
    r : int = 0
    g : int = 0
    b : int = 0

The ordering methods are now implemented (overloading operators: < > <= >=), similarly to functools.total_ordering with stronger equality tests.

Hashable, Mutable

@dataclasses.dataclass(unsafe_hash=True)                        # override base `__hash__`
class Color:
    ...

Although the object is potentially mutable (possibly undesired), a hash is implemented.

Hashable, Immutable

@dataclasses.dataclass(frozen=True)                             # `eq=True` (default) to be immutable 
class Color:
    ...

A hash is now implemented and changing the object or assigning to attributes is disallowed.

Overall, the object is hashable if either unsafe_hash=True or frozen=True.

See also the original hashing logic table with more details.

Optimization

@dataclasses.dataclass(slots=True)              # py310+
class SlottedColor:
    #__slots__ = ["r", "b", "g"]                # alternative
    r : int
    g : int
    b : int

The object size is now reduced:

>>> imp sys
>>> sys.getsizeof(Color)
1056
>>> sys.getsizeof(SlottedColor)
888

slots=True was added in Python 3.10. (Thanks @ajskateboarder).

In some circumstances, slots=True/__slots__ also improves the speed of creating instances and accessing attributes. Also, slots do not allow default assignments; otherwise, a ValueError is raised. If __slot__ already exists, slots=True will cause a TypeError.

See more on slots in this blog post.

See more on arguments added in Python 3.10+: match_args, kw_only, slots, weakref_slot.

What you don't get

To get the following features, special methods must be manually implemented:

Unpacking

@dataclasses.dataclass
class Color:
    r : int = 0
    g : int = 0
    b : int = 0

    def __iter__(self):
        yield from dataclasses.astuple(self)

Summary Table

+----------------------+----------------------+----------------------------------------------------+-----------------------------------------+
|       Feature        |       Keyword        |                      Example                       |           Implement in a Class          |
+----------------------+----------------------+----------------------------------------------------+-----------------------------------------+
| Attributes           |  init                |  Color().r -> 0                                    |  __init__                               |
| Representation       |  repr                |  Color() -> Color(r=0, g=0, b=0)                   |  __repr__                               |
| Comparision*         |  eq                  |  Color() == Color(0, 0, 0) -> True                 |  __eq__                                 |
|                      |                      |                                                    |                                         |
| Order                |  order               |  sorted([Color(0, 50, 0), Color()]) -> ...         |  __lt__, __le__, __gt__, __ge__         |
| Hashable             |  unsafe_hash/frozen  |  {Color(), {Color()}} -> {Color(r=0, g=0, b=0)}    |  __hash__                               |
| Immutable            |  frozen + eq         |  Color().r = 10 -> TypeError                       |  __setattr__, __delattr__               |
| Optimization         |  slots               |  sys.getsizeof(SlottedColor) -> 888                |  __slots__                              |
|                      |                      |                                                    |                                         |
| Unpacking+           |  -                   |  r, g, b = Color()                                 |  __iter__                               |
+----------------------+----------------------+----------------------------------------------------+-----------------------------------------+

* __ne__ is not needed and thus not implemented.

+These methods are not automatically generated and require manual implementation in a dataclass.


Additional features

Post-initialization

@dataclasses.dataclass
class RGBA:
    r : int = 0
    g : int = 0
    b : int = 0
    a : float = 1.0

    def __post_init__(self):
        self.a : int =  int(self.a * 255)


RGBA(127, 0, 255, 0.5)
# RGBA(r=127, g=0, b=255, a=127)

Inheritance

@dataclasses.dataclass
class RGBA(Color):
    a : int = 0

Conversions

Convert a dataclass to a tuple or a dict, recursively:

>>> dataclasses.astuple(Color(128, 0, 255))
(128, 0, 255)
>>> dataclasses.asdict(Color(128, 0, 255))
{'r': 128, 'g': 0, 'b': 255}

Limitations

  • Lacks mechanisms to handle starred arguments
  • Working with nested dataclasses can be complicated

References

  • R. Hettinger's talk on Dataclasses: The code generator to end all code generators
  • T. Hunner's talk on Easier Classes: Python Classes Without All the Cruft
  • Python's documentation on hashing details
  • Real Python's guide on The Ultimate Guide to Data Classes in Python 3.7
  • A. Shaw's blog post on A brief tour of Python 3.7 data classes
  • E. Smith's github repository on dataclasses
🌐
Medium
medium.com › @laurentkubaski › python-data-classes-f98f8368f5c2
Python Data Classes. This is a quick intro to Python Data… | by Laurent Kubaski | Medium
November 25, 2025 - @dataclass(unsafe_hash=True) class MyDataClass: var1: str var2: int # non-frozen Data Class: __hash__() method is STILL generated because of unsafe_hash=True assert [name for (name, value) in inspect.getmembers(MyDataClass, predicate=inspect.isfunction)] == ['__eq__', '__hash__', '__init__', '__repr__'] my_dataclass = MyDataClass("Hello", 5) assert my_dataclass.__hash__ is not None · The official Python documentation is amazingly unclear on why you would want to do this: “This might be the case if your class is logically immutable but can still be mutated.
🌐
DataCamp
datacamp.com › tutorial › python-data-classes
Python Data Classes: A Comprehensive Tutorial | DataCamp
March 15, 2024 - Despite all their features, data ... functionality. Here is the Exercise class again: from dataclasses import dataclass @dataclass class Exercise: name: str reps: int sets: int weight: float ex1 = Exercise("Bench press", 10, 3, 52.5) # Verifying Exercise is a regular class ex1.name ...
🌐
W3Schools
w3schools.com › python › ref_module_dataclasses.asp
Python dataclasses Module
Python Examples Python Compiler Python Exercises Python Quiz Python Challenges Python Practice Problems Python Server Python Syllabus Python Study Plan Python Interview Q&A Python Training ... from dataclasses import dataclass @dataclass class Point: x: int y: int p = Point(1, 2) print(p) Try it Yourself »
🌐
Python Course
python-course.eu › oop › dataclasses-in-python.php
5. Dataclasses In Python | OOP | python-course.eu
February 19, 2025 - Here, the dataclass decorator automates the generation of special methods like __init__, reducing the need for boilerplate code. The class definition is concise, making it clearer and more maintainable, especially as the number of attributes increases. This example demonstrates how using dataclasses for a class primarily used to store data, such as a robot representation, offers a more streamlined and readable alternative to traditional class structures.
🌐
Reddit
reddit.com › r/python › why you should use data classes in python
r/Python on Reddit: Why you should use Data Classes in Python
September 16, 2022 - Dataclasses don't play very well with custom __slots__ and I find it very annoying to fight with them over private variables and descriptors. Imo, the best thing about them is their __repr__ implementation. Using attrs or pydantic will make you drop them very fast. ... Besides the inheritance... You can use like a named tuple or dictionary for most applications? ... I love this articles explanation of inheritance. ... Python dataclasses will save you HOURS, also featuring attrs https://www.youtube.com/watch?v=vBH6GRJ1REM
🌐
iO Flood
ioflood.com › blog › python-dataclass-funadmentals-and-usage-guide-with-examples
Python Dataclass | Funadmentals, Usage, and Examples
March 12, 2024 - ... from dataclasses import dataclass @dataclass class Example: field1: int field2: str example = Example(1, 'example') print(example) # Output: # Example(field1=1, field2='example')
🌐
Pydantic
docs.pydantic.dev › 2.3 › usage › dataclasses
Dataclasses | Pydantic Docs
Note that the dataclasses.dataclass from Python stdlib implements only the __post_init__ method since it doesn’t run a validation step.
🌐
Medium
medium.com › @akashsdas_dev › dataclasses-in-python-804db8e149c3
Dataclasses in Python. Reduce writing boilerplate code when… | by AkashSDas | Medium
March 23, 2024 - Here, dataclass decorator will automatically generates several special methods, such as __init__, __repr__, __eq__, __hash__, and __str__. Note that in the above example, in order to make GameWeapon comparable we’ll have to take additional steps (which aren’t part of dataclass usage).
🌐
LinkedIn
linkedin.com › pulse › supercharge-your-python-code-dataclasses-ash-johnson
Supercharge your Python code with Dataclasses
November 13, 2022 - We can now remove the __init__ and__repr__ functions as the dataclass handles everything for us. In addition, when we print the person we get the following result: Person(first_name=’John’, last_name=’Doe’) we can even print the Person as a dictionary by using person.__dict__ which would give us the following output: {‘first_name’: ‘John’, ‘last_name’: ‘Doe’} In our example we have used two string variables, however, we can use any data types for our variables from int, str, dict, list and even functions.
🌐
Real Python
realpython.com › ref › stdlib › dataclasses
dataclasses | Python Standard Library – Real Python
In this example, the dataclasses module streamlines the creation and management of employee records. ... Learn how a Python dataclass reduces boilerplate, adds type hints and defaults, supports ordering and frozen instances, and still plays ...
🌐
Python
peps.python.org › pep-0557
PEP 557 – Data Classes | peps.python.org
Because the fields are in insertion order, derived classes override base classes. An example: @dataclass class Base: x: Any = 15.0 y: int = 0 @dataclass class C(Base): z: int = 10 x: int = 15
🌐
OneUptime
oneuptime.com › home › blog › how to use dataclasses in python
How to Use dataclasses in Python
January 25, 2026 - Python's dataclasses module, introduced in Python 3.7, provides a decorator and functions for automatically generating special methods like __init__, __repr__, and __eq__.