Normal classes vs data classes in Python: Key differences

Normal classes vs data classes in Python: Key differences

October 14, 2024

Python offers two popular approaches for defining classes: normal classes and data classes. Understanding the strengths and weaknesses of each helps you choose the right tool for the job.

Normal classes: The classic choice

Normal classes are the workhorses of object-oriented programming in Python. They provide a flexible blueprint for creating objects with custom attributes and methods.

Key features:

  1. Customisation: Define any methods and attributes needed.
  2. Flexibility: Modify attributes after object creation (mutable).
  3. Control: Granular control over object behaviour and interactions.

Ideal use cases:

  1. Complex objects with unique behaviours.
  2. Situations requiring custom logic or state management.
  3. Classes intended for inheritance and extension.

Data classes: Streamlined data structures

Data classes arrived in Python 3.7 in June 2018 (PEP 557) and are designed specifically for storing data. You add the @dataclass decorator to a class with type-annotated fields, and Python generates the boilerplate for you.

Key features:

  1. Conciseness: Less code, because __init__(), __repr__() and __eq__() are generated automatically from the fields.
  2. Mutable by default: Attributes can be changed after creation. Declare the class with @dataclass(frozen=True) to make instances read-only; assigning to a field then raises an exception.
  3. Type hints: Fields are declared with type annotations, which improve readability and help type checkers, although Python does not enforce them at runtime.
  4. Equality and hashing: Instances with the same field values compare as equal. A default data class is unhashable, so it cannot be a dictionary key or a set member; it becomes hashable with frozen=True (or unsafe_hash=True, which the documentation does not recommend).
  5. Extra options: order=True adds comparison operators; since Python 3.10, slots=True and kw_only=True are also available.

Ideal use cases:

  1. Simple data structures with well-defined attributes.
  2. Read-only value objects, declared with frozen=True.
  3. Efficient data transfer and serialisation.
  4. Integrating with data-driven frameworks.

Read on: Is your digital transformation initiative really working?

Choosing the right tool

When to choose a data class:

  1. Need a simple data holder with minimal behaviour.
  2. Value code conciseness and readability.
  3. Want immutable, hashable records for data integrity (use frozen=True).

When to choose a normal class:

  1. Custom methods or logic are required for object behaviour.
  2. Need full control over how objects are initialised and how their attributes are set.
  3. Plan to extend functionality through inheritance.

By understanding these distinctions, you can use the strengths of both normal and data classes to create robust and well-structured Python custom applications. For every option and default, see the official dataclasses documentation.

4KSoft-logo