Dataclasses¶
When working with classes, a lot of boiler-plate code is often required:
always __init__, __repr__, often __eq__, __lt__ for comparisons,
often __hash__ when instances are used in sets or as dict keys,
sometimes ‘neutral representation’ astuple, asdict as an export interface.
Dataclasses does the job for you and are a huge time saver.
Note
It seems at first glance that class attributes are defined.
However, this syntax in the context of a dataclass is called a field.
It will actually create class instances with independent attributes.
To explicitly define a class attribute, the typing.ClassVar type is required.
dataclasses_usage¶
1from dataclasses import dataclass, field
2from typing import ClassVar
3
4
5@dataclass(order=True) # allow ordering between instances
6class Student:
7 last_name: str
8 first_name: str
9 middle_names: list = field(default_factory=list) # for a list instance attribute
10
11 id: int = field(init=False) # not set by user, but automatically after init
12 nb_students: ClassVar[int] = 0 # a class attribute shared between instances
13
14 def __post_init__(self): # optional, here used to fill automatically the "id"
15 self.id = self._generate_unique_id()
16
17 @classmethod
18 def _generate_unique_id(cls):
19 cls.nb_students += 1
20 return cls.nb_students
21
22
23def main() -> None:
24 student = Student("D", "a", ["b", "c"]) # using positional
25 other_student = Student(
26 first_name="a",
27 last_name="E",
28 ) # using keywords
29 print(student)
30 print(other_student)
31 print(student < other_student)
32 # the field order is the comparison order (lastname, then firstname, ...)
33
34
35if __name__ == "__main__":
36 main()