Added "event" that gets called when an attribute of the instance gets modified.

This commit is contained in:
The Wobbler 2024-12-23 19:21:40 +01:00
parent 10ba70d545
commit 871b732ed9

View file

@ -8,13 +8,34 @@ import os
import json import json
def load_dataclass_json(dataclass, file_path: str, builtin_save: bool=True): def _on_attribute_change(self, key, value):
# call function without automatically passing "self" as argument using __func__ -
# and if it returns "True", set the attribute
if key == "attribute_change_event" or self.attribute_change_event.__func__(self.app, key, value):
self.__dict__[key] = value
def _set_attribute_change_event(self, event):
self.attribute_change_event = event
def load_dataclass_json(
dataclass,
file_path: str,
app: any=None,
builtin_save: bool=True,
builtin_change_event: bool=True
):
""" """
Loads a dataclass instance from a json file. Loads a dataclass instance from a json file.
:param dataclass: The dataclass from which the instance will be created. :param dataclass: The dataclass from which the instance will be created.
:param str file_path: The path to the json file from which the data gets loaded. :param str file_path: The path to the json file from which the data gets loaded.
:param app: This is necessary if you want the dataclass to execute a function on attribute change.
:param bool builtin_save: If True, you can simply call instance.save(file_path) to store the data. :param bool builtin_save: If True, you can simply call instance.save(file_path) to store the data.
:param bool builtin_change_event: If True, the returned instance will call the instance.attribute_change_event
on the specified app.
:return: An instance of the dataclass containing the data from the json file. :return: An instance of the dataclass containing the data from the json file.
""" """
@ -28,9 +49,19 @@ def load_dataclass_json(dataclass, file_path: str, builtin_save: bool=True):
instance = dataclass(**class_dict) instance = dataclass(**class_dict)
if not app is None:
instance.app = app
if builtin_save: # add save method so that we can easily do "instance.save()" if builtin_save: # add save method so that we can easily do "instance.save()"
dataclass.save = save_dataclass_json dataclass.save = save_dataclass_json
if builtin_change_event:
if app is None:
raise TypeError("You need to specify the app, else this won't work.")
dataclass.set_attribute_change_event = _set_attribute_change_event
dataclass.__setattr__ = _on_attribute_change
return instance return instance
@ -42,6 +73,9 @@ def save_dataclass_json(class_instance, file_path: str, indent: None | int | str
:param None|int|str indent: The indentation level for cleaner output. :param None|int|str indent: The indentation level for cleaner output.
""" """
if hasattr(class_instance, "app"): # remove app because it can't and doesn't need to be stored in the file
del class_instance.app
class_dict = class_instance.__dict__ class_dict = class_instance.__dict__
class_dict = dict(filter(lambda pair: not callable(pair[1]), class_dict.items())) # filter out functions class_dict = dict(filter(lambda pair: not callable(pair[1]), class_dict.items())) # filter out functions