Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import dataclasses
- import inspect
- from pathlib import Path
- import json
- class JsonSerializable:
- @classmethod
- def from_json(cls, path: Path | str, post_init_setattr: bool = False):
- """
- Loads a JSON file and creates an object with loaded data.
- Works fine with typing.NamedTuple / typing.TypedDict / dataclasses.dataclass.
- The object's `__init__` method must accept ALL the object attributes as keyword-possible arguments.
- """
- if cls == JsonSerializable:
- raise TypeError('Cannot load to JsonSerializable itself.'
- ' Maybe you want to inherit your class from JsonSerializable to load from JSON?')
- with open(path) as f:
- attrs = json.load(f)
- if not post_init_setattr:
- return cls(**attrs)
- sig = inspect.signature(cls.__init__)
- init_attrs = {k: v for k, v in attrs.items() if sig.parameters.get(k)}
- other_attrs = dict(set(attrs.items()) - set(init_attrs.items()))
- obj = cls(**init_attrs)
- for name, value in other_attrs.items():
- setattr(obj, name, value)
- return obj
- def to_json(self, path: Path | str):
- """
- Saves the object attributes to JSON file.
- Be aware that ALL the attributes will be saved.
- Works fine with typing.NamedTuple / typing.TypedDict / dataclasses.dataclass.
- """
- if self.__class__ == JsonSerializable:
- raise TypeError('Cannot save from JsonSerializable itself.'
- ' Maybe you want to inherit your class from JsonSerializable to save to JSON?')
- with open(path, 'w+') as f:
- json.dump(vars(self), f)
- def main():
- # example class
- @dataclasses.dataclass
- class Data(JsonSerializable):
- field1: int
- field2: float
- field3: str
- # loading
- data = Data.from_json('initial.json')
- # doing some data manipulations
- assert data.field3 == 'pending', f'Expected "pending" status, got {data.field3}'
- data.field1 = int(data.field2 % 3)
- data.field2 = .0
- data.field3 = 'success'
- # saving
- data.to_json('result.json')
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement