
Normal classes vs data classes in Python: Key differences
October 14, 2024Python 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:
- Customisation: Define any methods and attributes needed.
- Flexibility: Modify attributes after object creation (mutable).
- Control: Granular control over object behaviour and interactions.
Ideal use cases:
- Complex objects with unique behaviours.
- Situations requiring custom logic or state management.
- 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:
- Conciseness: Less code, because __init__(), __repr__() and __eq__() are generated automatically from the fields.
- 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.
- Type hints: Fields are declared with type annotations, which improve readability and help type checkers, although Python does not enforce them at runtime.
- 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).
- Extra options: order=True adds comparison operators; since Python 3.10, slots=True and kw_only=True are also available.
Ideal use cases:
- Simple data structures with well-defined attributes.
- Read-only value objects, declared with frozen=True.
- Efficient data transfer and serialisation.
- Integrating with data-driven frameworks.
Read on: Is your digital transformation initiative really working?
Choosing the right tool
When to choose a data class:
- Need a simple data holder with minimal behaviour.
- Value code conciseness and readability.
- Want immutable, hashable records for data integrity (use frozen=True).
When to choose a normal class:
- Custom methods or logic are required for object behaviour.
- Need full control over how objects are initialised and how their attributes are set.
- 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.