Convert nested Python dict to object?

后端 未结 30 2450
时光取名叫无心
时光取名叫无心 2020-11-22 09:28

I\'m searching for an elegant way to get data using attribute access on a dict with some nested dicts and lists (i.e. javascript-style object syntax).

For example:

30条回答
  •  野性不改
    2020-11-22 10:19

    If you want to access dict keys as an object (or as a dict for difficult keys), do it recursively, and also be able to update the original dict, you could do:

    class Dictate(object):
        """Object view of a dict, updating the passed in dict when values are set
        or deleted. "Dictate" the contents of a dict...: """
    
        def __init__(self, d):
            # since __setattr__ is overridden, self.__dict = d doesn't work
            object.__setattr__(self, '_Dictate__dict', d)
    
        # Dictionary-like access / updates
        def __getitem__(self, name):
            value = self.__dict[name]
            if isinstance(value, dict):  # recursively view sub-dicts as objects
                value = Dictate(value)
            return value
    
        def __setitem__(self, name, value):
            self.__dict[name] = value
        def __delitem__(self, name):
            del self.__dict[name]
    
        # Object-like access / updates
        def __getattr__(self, name):
            return self[name]
    
        def __setattr__(self, name, value):
            self[name] = value
        def __delattr__(self, name):
            del self[name]
    
        def __repr__(self):
            return "%s(%r)" % (type(self).__name__, self.__dict)
        def __str__(self):
            return str(self.__dict)
    

    Example usage:

    d = {'a': 'b', 1: 2}
    dd = Dictate(d)
    assert dd.a == 'b'  # Access like an object
    assert dd[1] == 2  # Access like a dict
    # Updates affect d
    dd.c = 'd'
    assert d['c'] == 'd'
    del dd.a
    del dd[1]
    # Inner dicts are mapped
    dd.e = {}
    dd.e.f = 'g'
    assert dd['e'].f == 'g'
    assert d == {'c': 'd', 'e': {'f': 'g'}}
    

提交回复
热议问题