Python dataclasses
Background
Although I work quite much with python I really hate the aspect of dynamically typing when using classes. In my opinion you should do on object oriented modelling to define attributes instead of adding attributes during runtime.
I would like to have something like perls use strict to at least define the attributes, even if the datatype is missing there.
Python 3.7, pep 557 introduced dataclasses to the default library, which enables the developer to do an object oriented modelling with python. Additionally dataclass_json is a simple addition to serialize dataclasses to json files.
Notes to the example
Never use the __init__
method, this is generated internally, instead use the __post_init__
method optionally with InitVar
attributes. You wont see the InitVar
attributes in the JSON file.
Implementation example
code
1from dataclasses import dataclass, field, InitVar
2from dataclasses_json import dataclass_json
3from typing import List, Dict
4
5import json
6
7@dataclass_json
8@dataclass
9class AnotherClass:
10 a_integer_att: int = field(default=None)
11
12@dataclass_json
13@dataclass
14class ExampleClass:
15 """Simple Example class with reference to another class."""
16 identificator: str = field(default=None)
17
18 a_list_of_strings: List[str] = field(default_factory=list)
19 """List[str]: A list of strings."""
20
21 a_dict_of_objects: Dict[str, AnotherClass] = field(default_factory=dict)
22 """Dict[str, Field]: A dictionary of objects of AnotherClass."""
23
24 a_helper: InitVar[str] = None
25
26 def __post_init__(self, a_helper):
27 print(
28 f"post init is called from generated (never overwrite it!) card.__init__() with a_helper='{a_helper}'")
29
30if __name__ == '__main__':
31 print("card with constructor in main.")
32 ea = ExampleClass("id01", a_dict_of_objects={"a": AnotherClass(1), "b": AnotherClass(99)}, a_helper="hey ho!")
33 outfile_name = r"C:\temp\dataclass_example.json"
34
35 print(f" * original id of object is {id(ea)}")
36 # writing
37 with open(outfile_name, 'w') as file:
38 json.dump(ea.to_dict(), file, indent=2)
39
40 # reading
41 with open(outfile_name, 'r') as file:
42 object_as_json = json.load(file)
43 print("object from json file.")
44 ea = ExampleClass.from_dict(object_as_json)