Skip to main content
A data class is a class decorated with @dataclass from the dataclasses module, introduced in Python 3.7. It utilizes PEP 526 variable annotations to automatically generate boilerplate special methods (dunder methods)—such as __init__(), __repr__(), and __eq__()—directly into the class namespace based on the defined attributes.

Basic Syntax

To define a data class, apply the @dataclass decorator and declare class variables with type hints.
When the Python interpreter processes this decorator, it dynamically synthesizes the following methods:
  1. __init__(self, x: float, y: float, z: float = 0.0): Initializes the instance variables.
  2. __repr__(self): Returns a string representation, e.g., Point(x=1.0, y=2.0, z=0.0).
  3. __eq__(self, other): Compares the class instances as if they were tuples of their fields.

Decorator Parameters

The @dataclass decorator accepts several boolean arguments to control which methods are generated and how the class behaves:
Setting frozen=True simulates immutability by overriding __setattr__() and __delattr__() to raise a FrozenInstanceError if attribute modification is attempted after initialization. It also automatically generates a __hash__() method, making the instances hashable.

The field() Function

For granular control over individual attributes, the field() function is used. It allows you to exclude specific fields from generated methods or handle mutable default values.
Key parameters of field() include:
  • default: The default value for the field.
  • default_factory: A zero-argument callable called to initialize a field’s value (required for mutable types like list or dict).
  • init: If False, the field is excluded from the generated __init__().
  • repr: If False, the field is excluded from the generated __repr__().
  • compare: If False, the field is excluded from generated equality and ordering methods.

Post-Initialization Processing

Because the @dataclass decorator overwrites the __init__() method, custom initialization logic cannot be placed there. Instead, the dataclasses module provides the __post_init__() hook. If defined on the class, the generated __init__() method will automatically call __post_init__() immediately after all fields have been initialized.
If the class is defined with frozen=True, __post_init__() must use object.__setattr__(self, 'name', value) to bypass the immutability constraints during the post-initialization phase.
Tired of Poor Python Skills? Fix That With Deep Grasping!Learn More