Created
May 3, 2020 02:26
-
-
Save mkpoli/8ff5447880333d6a9e3ad177d86b9540 to your computer and use it in GitHub Desktop.
Python: Save Object Attributes to Config File Recursively based on a Data Map
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from typing import Callable, TypeVar | |
| from io import FileIO | |
| T = TypeVar("T") | |
| def replace_value(data: dict, data_object: object) -> dict: | |
| result = data | |
| for k, v in data.items(): | |
| if isinstance(v, dict): | |
| result[k] = replace_value(v, data_object) | |
| else: | |
| result[k] = getattr(data_object, k) | |
| return result | |
| def save(data_map: dict, data_object: T, dump: Callable, file: FileIO): | |
| data = replace_value(data_map, data_object) | |
| dump(data, file) | |
| def apply_value(data_map: dict, data: dict, data_object: object): | |
| for k, v in data_map.items(): | |
| if isinstance(v, dict): | |
| return apply_value(v, data[k], data_object) | |
| else: | |
| setattr(data_object, k, v) | |
| return data_object | |
| def load(data_map: dict, data_object: T, _load: Callable, file: FileIO) -> T: | |
| data = _load(file) | |
| return apply_value(data_map, data, data_object) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import config | |
| import json | |
| import toml | |
| import yaml | |
| from pathlib import Path | |
| testfile_json_path = Path(__file__).parent / "config.json" | |
| testfile_toml_path = Path(__file__).parent / "config.toml" | |
| testfile_yaml_path = Path(__file__).parent / "config.yaml" | |
| data_map = { | |
| "x": { | |
| "x_a": "y_a", | |
| "x_b": "y_b" | |
| } | |
| } | |
| class TestObject: | |
| def __init__(self) -> None: | |
| self.x_a = "A" | |
| self.x_b = "B" | |
| def __str__(self) -> str: | |
| return f"x_a = { self.x_a }, x_b = { self.x_b }" | |
| if __name__ == "__main__": | |
| test_object = TestObject() | |
| with open(testfile_json_path, "w") as f: | |
| config.save(data_map, test_object, json.dump, f) | |
| with open(testfile_toml_path, "w") as f: | |
| config.save(data_map, test_object, toml.dump, f) | |
| with open(testfile_yaml_path, "w") as f: | |
| config.save(data_map, test_object, yaml.dump, f) | |
| with open(testfile_json_path, "r") as f: | |
| print(config.load(data_map, test_object, json.load, f)) | |
| with open(testfile_toml_path, "r") as f: | |
| print(config.load(data_map, test_object, toml.load, f)) | |
| with open(testfile_yaml_path, "r") as f: | |
| print(config.load(data_map, test_object, yaml.safe_load, f)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment