Skip to content

Instantly share code, notes, and snippets.

@mkpoli
Created May 3, 2020 02:26
Show Gist options
  • Select an option

  • Save mkpoli/8ff5447880333d6a9e3ad177d86b9540 to your computer and use it in GitHub Desktop.

Select an option

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
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)
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