Oct 22nd, 2021 - written by Kimserey with .
A data class is a class which is identified by the value stored in their attributes. The most common way of holding values in Python is via tuples. Data classes make is easier to construct a class with a name and meaning while keeping the value aspect in term of equality. In today’s post we will see how we can define data classes using the dataclass
decorator from the dataclasses
module.
dataclass
attribute provides an easy way to make a class behave as a data type rather than a reference type:
1
2
3
4
5
6
7
In [6]: from dataclasses import dataclass
...:
...: @dataclass
...: class Pet:
...: name: str
...: age: int
...:
Adding the dataclass
decorator generates all special methods for the class which will make it behave as a data class. The major advantage is that the equality is then checked against fields:
1
2
3
4
5
6
7
8
9
10
11
12
13
In [7]: philou = Pet("philou", 12)
In [8]: bento = Pet("bento", 1)
In [9]: philou == bento
Out[9]: False
In [10]: bento.name = "philou"
In [11]: bento.age = 12
In [12]: philou == bento
Out[12]: True
Here we defined two instances - once we set the name
and age
as the same values, we can see that the equality shows that philou
is equal to bento
.
The decorator also adds the useful __repr__()
:
1
2
In [13]: philou
Out[13]: Pet(name='philou', age=12)
Another nice feature is that a constructor is created for us automatically. As we saw earlier, we never defined any __init__
yet we were able to initialise our classes:
1
In [8]: bento = Pet("bento", 1)
The decorator can take arguments which allows to define some extra functionalities:
1
@dataclasses.dataclass(*, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False)
By default, we have the init
, repr
and eq
generated. The decorator takes other arguments which are useful. For example, order
can be set to True
to make the class implement comparison.
1
2
3
4
5
6
7
8
9
10
11
In [30]: @dataclass(order=True)
...: class Pet:
...: name: str
...: age: int
In [34]: bento1 = Pet("bento", 1)
In [35]: bento2 = Pet("bento", 2)
In [36]: bento1 < bento2
Out[36]: True
The fields are compared in order one by one to define the ordering.
Lastly frozen
will make the class sort of immutable by preventing changes on the attributes:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
In [37]: @dataclass(frozen=True)
...: class Pet:
...: name: str
...: age: int
In [38]: bento1 = Pet("bento", 1)
In [39]: bento1.name = "hello"
---------------------------------------------------------------------------
FrozenInstanceError Traceback (most recent call last)
<ipython-input-39-19f49e38d813> in <module>
----> 1 bento1.name = "hello"
<string> in __setattr__(self, name, value)
FrozenInstanceError: cannot assign to field 'name'
And that concludes this post on the usage of the dataclass
attribute!
Today we looked at how to create data classes in Python using the dataclass
decorator. We started by looking at the default behaviour and then moved on to try extra parameters to specify ordering and immutability. I hope you liked this post and I see you on the next one!