/
🐍

Python Dataclass

https://docs.python.org/3/library/dataclasses.html
python
On this page

Python Dataclass

The dataclasses module, a feature introduced in Python 3.7, provides a way to create data classes in a simpler manner without the need to write methods. A data class is a class typically containing mainly data, although there aren't really any restrictions. It is created using the new @dataclass decorator.

python
from dataclasses import dataclass
@dataclass
class DataClassCard:
rank: str
suit: str

A data class is a regular Python class. The only thing that sets it apart is that it has basic data model methods like .__init__(), .__repr__(), and .__eq__() implemented for you.

python
queen_of_hearts = DataClassCard('Q', 'Hearts')
print(queen_of_hearts.rank)
print(queen_of_hearts == DataClassCard('Q', 'Hearts'))

Default Values

It is easy to add default values to the fields of your data class.

python
from dataclasses import dataclass
@dataclass
class Position:
name: str
lon: float = 0.0
lat: float = 0.0

Type Hints

So far, we have not made a big fuss of the fact that data classes support typing out of the box. You have probably noticed that we defined the fields with a type hint: name: str says that name should be a text string (str type).

python
from dataclasses import dataclass
from typing import Any
@dataclass
class WithoutExplicitTypes:
name: Any
value: Any = 42

Adding Methods

You already know that a data class is just a regular class. That means that you can freely add your own methods to a data class.

python
from dataclasses import dataclass
from math import asin, cos, radians, sin, sqrt
@dataclass
class Position:
name: str
lon: float = 0.0
lat: float = 0.0
def distance_to(self, other):
r = 6371 # Earth radius in kilometers
lam_1, lam_2 = radians(self.lon), radians(other.lon)
phi_1, phi_2 = radians(self.lat), radians(other.lat)
h = (sin((phi_2 - phi_1) / 2)**2
+ cos(phi_1) * cos(phi_2) * sin((lam_2 - lam_1) / 2)**2)
return 2 * r * asin(sqrt(h))

More Flexible Data Classes

Some more advanced features like parameters to the @dataclass decorator and the field() function.

python
from dataclasses import dataclass
from typing import List
@dataclass
class PlayingCard:
rank: str
suit: str
@dataclass
class Deck:
cards: List[PlayingCard]

Advanced Default Values

Data classes use something called a default_factory to handle mutable default values. To use default_factory (and many other cool features of data classes), you need to use the field() specifier.

python
from dataclasses import dataclass, field
from typing import List
RANKS = '2 3 4 5 6 7 8 9 10 J Q K A'.split()
SUITS = '♣ ♢ ♡ ♠'.split()
def make_french_deck():
return [PlayingCard(r, s) for s in SUITS for r in RANKS]
@dataclass
class Deck:
cards: List[PlayingCard] = field(default_factory=make_french_deck)

The field() specifier is used to customize each field of a data class individually. You will see some other examples later. For reference, these are the parameters field() supports:

  • default: Default value of the field
  • default_factory: Function that returns the initial value of the field
  • init: Use field in .__init__() method? (Default is True.)
  • repr: Use field in repr of the object? (Default is True.)
  • compare: Include the field in comparisons? (Default is True.)
  • hash: Include the field when calculating hash()? (Default is to use the same as for compare.)
  • metadata: A mapping with information about the field
python
from dataclasses import dataclass, field
@dataclass
class Position:
name: str
lon: float = field(default=0.0, metadata={'unit': 'degrees'})
lat: float = field(default=0.0, metadata={'unit': 'degrees'})

Immutable Data Classes

To make a data class immutable, set frozen=True when you create it.

python
from dataclasses import dataclass
@dataclass(frozen=True)
class Position:
name: str
lon: float = 0.0
lat: float = 0.0

Inheritance

You can subclass data classes quite freely.

python
from dataclasses import dataclass
@dataclass
class Position:
name: str
lon: float
lat: float
@dataclass
class Capital(Position):
country: str

Optimizing Data Classes

Slots can be used to make classes faster and use less memory. Data classes have no explicit syntax for working with slots, but the normal way of creating slots works for data classes as well.

python
from dataclasses import dataclass
@dataclass
class SimplePosition:
name: str
lon: float
lat: float
@dataclass
class SlotPosition:
__slots__ = ['name', 'lon', 'lat']
name: str
lon: float
lat: float
Want to make your own site like this?
Try gatsby-theme-code-notes by Zander Martineau.
Life of Code