2

Given this bunch of python objects (lists and dicts):

d = [
   {
      'props': {
         'columns': [
            {
               'field': 'Hello'
            }
         ]
      }
   }
]

How would I use a string using dot-notation to return the 'field' value?:

get(d, "[0].props.columns[0].field") # "get" is fictitious and just an example
>>> 'Hello'

I found this article below which talks about converting the dicts into Python object to allow dot-notation, however I'm unsure how to make it usable with a string representation of the dot-notation. https://johschmidt42.medium.com/how-to-transform-a-dict-to-an-object-in-python-ba0c7ef0fd95 E.g. This works:

# this works
d[0].props.columns[0].field

# this (obviously) doesn't
"d[0].props.columns[0].field"

## technically, the d[0] part doesn't work since the Dict2Object class init doesn't currently support an initial `list` object, but assume this *does* work (although I need to get this code working as well)

This is what I have currently:

import json

class Dict2Object:
    """
    @DynamicAttrs
    Class to transform a dict into a python object.
    """

    def __init__(self, in_dict):
        # type checking
        assert isinstance(in_dict, (dict, list))
        # iterate over dict
        if isinstance(in_dict, dict):
            for key, val in in_dict.items():
                # translate the string to not have white spaces, dashes and be lower case etc
                key = translate_string(key)
                # check if the value is a (tuple, list, set)
                if isinstance(val, (list, tuple, set)):
                    # set an attribute for every item in the Sequence
                    # if the value is a dict, use the Dict2Object class (recursive)
                    setattr(
                        self,
                        key,
                        [Dict2Object(x) if isinstance(x, dict) else x for x in val],
                    )
                else:
                    # if the value is not a (tuple, list, set)
                    # set an attribute for the value unless
                    # the value is a dict -> use the Dict2Object class (recursive)
                    setattr(self, key, Dict2Object(val) if isinstance(val, dict) else val)
    def __repr__(self):
        return "{%s}" % str(
            ", ".join("'%s': %s" % (k, repr(v)) for (k, v) in self.__dict__.items())
        )


def translate_string(string):
    string = string.replace("-", "_")
    string = string.replace(" ", "_")
    string = string.lower()
    return string

d = [
   {
      'props': {
         'columns': [
            {
               'field': 'Hello'
            }
         ]
      }
   }
]

d_obj = Dict2Object(d[0])
d_obj.props.columns[0].field
>>> 'Hello'
njminchin
  • 408
  • 3
  • 13

0 Answers0