I would like to implement a kind of mapper between db data and some other data like obtained from the response of API. The expected behavior is following: class IData: a: str = ('db_a', 'type_a') b: str = ('db_b', 'type_b') c: str = ('db_c', 'type_c') class MyData(IData): a = 'api_a' b = 'api_b' c = 'api_c' m = MyData() # or `m = MyData` m.a.db_name -> 'db_a' m.a.db_type -> 'db_b' m.a.api_name -> 'db_c' m.get_db_names() -> ['db_a', 'db_b', 'db_c'] m.get_db_types() -> ['type_a', 'type_b', 'type_c'] m.get_api_names() -> ['api_a', 'api_b', 'api_c'] # or Nones if some are not assigned in MyData definition I implemented it like following: class _Field: def __init__(self, db_name, db_type, api_name=None): self.db_name = db_name self.db_type = db_type self.api_name = api_name class _base: def get_db_names(self): return [self.__dict__.db_name for i in self.__dict__ if not i.startswith("_")] def get_db_types(self): return [self.__dict__.db_type for i in self.__dict__ if not i.startswith("_")] def get_api_names(self): return [self.__dict__.api_name for i in self.__dict__ if not i.startswith("_")] class IData(_base): def __init__(self): self.a = _Field("db_a", "type_a") self.b = _Field("db_b", "type_b") self.c = _Field("db_c", "type_c") class MyData(IData): def __init__(self): super().__init__() self.a.api_name = "api_a" self.b.api_name = "api_b" self.c.api_name = "api_c" Is there some better, simpler, more robust solution using dataclasses or types (namespaces) or something else? Also would be nice to rise an exception if for some attribute the api_name is not set in class MyData(IData) when the user is instantiating m = MyData() Continue reading...