Python Dataclass Python

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.

Create Dataclass

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)

Decorator Arguments

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!

Conclusion

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!

Designed, built and maintained by Kimserey Lam.