how to model simple nested data static structure instead of nested dictionaries (namedtuple, dataclass... )

Viewed 106

I hope there is some best practice or design pattern for use case of having simple nested data/mapping with need to pre-store data, select proper data group, and conveniently access specific values. Example - install script parameters where install script will be given type of install (a.k.a label) and based on that proper folder to install and other params values should be evaluated

Sample as nested dict

install_params = {'prod':{'folder_name':'production','param_1' : value_a ... }, 
                  'dev':{'folder_name':'development','param_1' : value_b ... },
                  'test':{'folder_name':'test', 'param_1' : value_c ... }}

Nested dicts offers grouping of all data under parent dict install_params so all labels can be present to user with install_params.keys(), and (in this case) sole required functionality - retrieving proper values for given installation type/label (simply via install_params[user_selected_label] ) However having either numerous items in parent dict, or more nested levels, or more complex structures as values of params, this will be cumbersome to use and error prone.

Thought of rewriting it as either collection.namedtuple or typing.NamedTuple or @dataclass or just generic class but neither seems to offer convenient solution to the generic use case above.

e.g. named tuple offers dot notation to access fields, but I still have to group them all somehow and implement functionality of selecting proper instance based

prod = InstallType( 'prod', 'prod', 'value_a')
dev = InstallType( 'dev', 'development ', 'value_b')
test = InstallType( 'test', 'test ', 'value_c')

all_types = [prod,dev, test]
if type =='prod': # select prod named tuple

in the end I've started to think to create dictionary of named tuples or a single data class that would keep the data mapping private and init itself based on label input parameter. The later would nicely encapsulate all functionality and allow dot notation, but still uses ugly nested dicts inside

@dataclass(frozen=True)
class SomeDataClass:
    label: str
    folder_name: str = None
    param_1: float = None

    def __post__init__(self):
        #dreaded nested_dict to populate self.folder_name and others based on submitted label
        (...)   

install_params = SomeDataClass(label=user_selection)
print(install_params.folder_name) # would work as expected since coded in SomeDataClass

This seemed promising, but SomeDataClass again produced further problems (How to expose all available install labels (prod, dev, test...) to user before instancing the class, how to presents fields as mandatory, but not requiring user to submit them, as they should be 'computed' based on submitted label. ( plain folder_name: str requires user to still submit it, while folder_name : str = None is confusing and suggest its optional and can be set to None ), etc... ) It also feels rather over-engineered solution for the simple nested dicts mappings

0 Answers
Related