递归DotDict

tpo*_*eux 8 python recursion dictionary

我有一个实用程序类,使得Python字典在获取和设置属性方面的行为有点像JavaScript对象.

class DotDict(dict):
    """
    a dictionary that supports dot notation 
    as well as dictionary access notation 
    usage: d = DotDict() or d = DotDict({'val1':'first'})
    set attributes: d.val2 = 'second' or d['val2'] = 'second'
    get attributes: d.val2 or d['val2']
    """
    __getattr__ = dict.__getitem__
    __setattr__ = dict.__setitem__
    __delattr__ = dict.__delitem__
Run Code Online (Sandbox Code Playgroud)

我想这样做它也将嵌套的字典转换成DotDict()实例.我希望能够做这样的事有__init____new__,但我还没有拿出任何的工作原理:

def __init__(self, dct):
    for key in dct.keys():
        if hasattr(dct[key], 'keys'):
            dct[key] = DotDict(dct[key])
Run Code Online (Sandbox Code Playgroud)

如何递归地将嵌套字典转换为DotDict()实例?

>>> dct = {'scalar_value':1, 'nested_dict':{'value':2}}
>>> dct = DotDict(dct)

>>> print dct
{'scalar_value': 1, 'nested_dict': {'value': 2}}

>>> print type(dct)
<class '__main__.DotDict'>

>>> print type(dct['nested_dict'])
<type 'dict'>
Run Code Online (Sandbox Code Playgroud)

Bop*_*reH 11

我没有看到你在构造函数中复制值的位置.因此,DotDict总是空的.当我添加键分配时,它工作:

class DotDict(dict):
    """
    a dictionary that supports dot notation 
    as well as dictionary access notation 
    usage: d = DotDict() or d = DotDict({'val1':'first'})
    set attributes: d.val2 = 'second' or d['val2'] = 'second'
    get attributes: d.val2 or d['val2']
    """
    __getattr__ = dict.__getitem__
    __setattr__ = dict.__setitem__
    __delattr__ = dict.__delitem__

    def __init__(self, dct):
        for key, value in dct.items():
            if hasattr(value, 'keys'):
                value = DotDict(value)
            self[key] = value


dct = {'scalar_value':1, 'nested_dict':{'value':2, 'nested_nested': {'x': 21}}}
dct = DotDict(dct)

print dct.nested_dict.nested_nested.x
Run Code Online (Sandbox Code Playgroud)

它看起来有点危险且容易出错,更不用说其他开发人员的无数惊喜,但似乎有效.


Ram*_*lat 6

厚颜无耻地塞我自己的包

有一个包可以完全满足您的需求,也可以做更多的事情,它被称为Prodict

from prodict import Prodict

life_dict = {'bigBang':
                {'stars':
                    {'planets': []}
                }
            }

life = Prodict.from_dict(life_dict)

print(life.bigBang.stars.planets)
# prints []

# you can even add new properties dynamically
life.bigBang.galaxies = []

Run Code Online (Sandbox Code Playgroud)

PS 1:我是该产品的作者。

PS 2:这是直接复制粘贴另一个问题的答案。