如何使用点“。” 访问字典成员?


282

如何通过点“。”访问Python词典成员?

例如,mydict['val']我不想写,而是想写mydict.val

我也想以这种方式访问​​嵌套的字典。例如

mydict.mydict2.val 

将指

mydict = { 'mydict2': { 'val': ... } }

20
以元组为键的dict可以更好或更好地服务于人们使用嵌套dict的许多情况,而d[a][b][c]替换为d[a, b, c]
Mike Graham

7
这不是魔术:foo = {}; foo [1,2,3] =“一,二,三!”; foo.keys()=> [(1,2,3)]
布莱恩·奥克利 Bryan Oakley)2010年

10
哇。再次哇。我不知道元组可能是字典的关键。哇第三次。
bodacydo

3
任何“可哈希”的对象都可以用作字典的键。大多数不可变对象也是可哈希的,但前提是它们的所有内容都是可哈希的。代码d [1、2、3]之所以有效,是因为“,”是“创建元组运算符”;它与d [(1,2,3)]相同。在元组的声明周围,括号通常是可选的。
拉里·黑斯廷斯

6
您是否考虑过钥匙本身带有圆点的情况{"my.key":"value"}?还是当关键字是关键字时,例如“ from”?我已经考虑过几次了,这是更多的问题和疑难解答,而不是预期的好处。
Todor Minakov

Answers:


147

您可以使用我刚刚制作的此类进行操作。通过此类,您可以Map像其他字典(包括json序列化)一样使用该对象,也可以使用点符号。希望对您有所帮助:

class Map(dict):
    """
    Example:
    m = Map({'first_name': 'Eduardo'}, last_name='Pool', age=24, sports=['Soccer'])
    """
    def __init__(self, *args, **kwargs):
        super(Map, self).__init__(*args, **kwargs)
        for arg in args:
            if isinstance(arg, dict):
                for k, v in arg.iteritems():
                    self[k] = v

        if kwargs:
            for k, v in kwargs.iteritems():
                self[k] = v

    def __getattr__(self, attr):
        return self.get(attr)

    def __setattr__(self, key, value):
        self.__setitem__(key, value)

    def __setitem__(self, key, value):
        super(Map, self).__setitem__(key, value)
        self.__dict__.update({key: value})

    def __delattr__(self, item):
        self.__delitem__(item)

    def __delitem__(self, key):
        super(Map, self).__delitem__(key)
        del self.__dict__[key]

用法示例:

m = Map({'first_name': 'Eduardo'}, last_name='Pool', age=24, sports=['Soccer'])
# Add new key
m.new_key = 'Hello world!'
# Or
m['new_key'] = 'Hello world!'
print m.new_key
print m['new_key']
# Update values
m.new_key = 'Yay!'
# Or
m['new_key'] = 'Yay!'
# Delete key
del m.new_key
# Or
del m['new_key']

21
为了使用Python 3,我更新.iteritems().items()
berto

13
请注意,这与常规期望的行为有所不同,因为AttributeError如果属性不存在,它将不会提高。相反,它将返回None
mic_e

建议添加getstatesetstate,以便深层复制和其他系统可以支持它。
user1363990

4
您可以将构造函数简化为self.update(*args,**kwargs)。另外,您可以添加__missing__(self,key): value=self[key]= type(self)(); return value。然后,您可以使用点表示法添加缺少的条目。如果您希望它是可选取的,则可以添加__getstate____setstate__
Jens Munk

1
这将使hasattr(Map, 'anystring') is true. which means the hasattr would always return True due to overriding __getattr__`

264

我一直将其保存在util文件中。您也可以在自己的类中将其用作混合。

class dotdict(dict):
    """dot.notation access to dictionary attributes"""
    __getattr__ = dict.get
    __setattr__ = dict.__setitem__
    __delattr__ = dict.__delitem__

mydict = {'val':'it works'}
nested_dict = {'val':'nested works too'}
mydict = dotdict(mydict)
mydict.val
# 'it works'

mydict.nested = dotdict(nested_dict)
mydict.nested.val
# 'nested works too'

5
很简单的答案,太好了!您是否偶然知道要在IPython中使用制表符完成功能,我需要做什么?该类将需要实现__dir __(self),但是以某种方式我无法使其正常工作。
andreas-h

8
为简单起见,+ 1。但似乎不适用于嵌套字典。d = {'foo': {'bar': 'baz'}}; d = dotdict(d); d.foo.bar引发属性错误,但d.foo工作正常。
tmthyjames

2
是的,这不适用于复杂的嵌套结构。
大卫,

16
@tmthyjames,您只需在getter方法中返回dotdict类型的对象即可以点表示法递归访问属性,例如: python class DotDict(dict): """dot.notation access to dictionary attributes""" def __getattr__(*args): val = dict.get(*args) return DotDict(val) if type(val) is dict else val __setattr__ = dict.__setitem__ __delattr__ = dict.__delitem__
TMKasun

4
经过实验,似乎get确实是一个坏主意,因为它会返回None而不是对丢失的项目引发错误……
NichtJens

117

dotmap通过安装pip

pip install dotmap

它可以完成您想要做的所有事情并成为其子类dict,因此它的作用类似于普通字典:

from dotmap import DotMap

m = DotMap()
m.hello = 'world'
m.hello
m.hello += '!'
# m.hello and m['hello'] now both return 'world!'
m.val = 5
m.val2 = 'Sam'

最重要的是,您可以将其与dict对象之间进行转换:

d = m.toDict()
m = DotMap(d) # automatic conversion in constructor

这意味着,如果您要访问的内容已经dict存在,可以将其转换DotMap为易于访问的内容:

import json
jsonDict = json.loads(text)
data = DotMap(jsonDict)
print data.location.city

最后,它会自动创建新的子DotMap实例,因此您可以执行以下操作:

m = DotMap()
m.people.steve.age = 31

与束比较

全面披露:我是DotMap的创建者。我创建它是因为Bunch缺少这些功能

  • 记住添加了订单项并按照该顺序进行迭代
  • 自动子 DotMap创建,这样可以节省时间,并在您具有多个层次结构时使代码更简洁
  • 从构造dict并将所有子dict实例递归转换为DotMap

2
:-)可以使用名称中已经点号的键吗?{"test.foo": "bar"}可以通过mymap.test.foo那访问。那太棒了。将平面地图转换为深层地图然后将DotMap应用于该地图需要一些回归,但这是值得的!
dlite922

整齐。通过Jupyter笔记本中的键,可以使制表符列表/完成功能起作用吗?点式访问对于交互式使用而言最有价值。
德米特里

@Dmitri酷产品。以前从未听说过,所以我不确定如何使其自动完成工作。我同意使用DotMap自动完成功能最有效。我使用Sublime Text,它可以自动完成以前键入的关键字。
克里斯·雷德福德

1
我发现它缺少诸如**kwargs或的字典提取功能c = {**a, **b}。实际上,它会悄悄地失败,提取时的行为就像一个空字典。
西蒙·斯特雷彻

@SimonStreicher我对此进行m = DotMap(); m.a = 2; m.b = 3; print('{a} {b}'.format(**m));了测试,并且得到了预期的效果2 3。如果您有证明有效的破损案例,dict()但不适用于DotMap(),请将代码提交至GitHub中的Issues标签。
克里斯·雷德福德

56

从指令派生并实施__getattr__和实施__setattr__

或者您可以使用非常相似的Bunch

我认为不可能对内置的dict类进行修补。


2
猴子补丁到底是什么意思?我听说过但是没用过。(对不起,我问这样的新手问题,我编程方面还不太好(我才是二年级学生。)
bodacydo 2010年

9
Monkeypatching正在使用Python(或其他语言)的动态性来更改通常在源代码中定义的内容。它尤其适用于在创建类后更改类的定义。
Mike Graham 2010年

如果您经常使用此功能,请注意Bunch的速度。我经常使用它,最终浪费了我三分之一的请求时间。查看我的答案,以获取对此的更详细说明。
JayD3e 2015年

22

Fabric具有非常好的,最小的实现。扩展它以允许嵌套访问,我们可以使用defaultdict,结果看起来像这样:

from collections import defaultdict

class AttributeDict(defaultdict):
    def __init__(self):
        super(AttributeDict, self).__init__(AttributeDict)

    def __getattr__(self, key):
        try:
            return self[key]
        except KeyError:
            raise AttributeError(key)

    def __setattr__(self, key, value):
        self[key] = value

如下使用它:

keys = AttributeDict()
keys.abc.xyz.x = 123
keys.abc.xyz.a.b.c = 234

这就详细说明了库格尔的回答:“从命令和实现中得出__getattr____setattr__”。现在您知道了!


1
那个很棒!
托马斯·克林格

包含defaultdict很高兴-但是,这似乎仅在从头开始执行dict时才起作用。如果需要将现有字典递归转换为“ dotdict”。这里有一个替代dotdict它允许将现有的dict递归对象:gist.github.com/miku/...
三苦

19

我尝试了这个:

class dotdict(dict):
    def __getattr__(self, name):
        return self[name]

你可以试试 __getattribute__

让每个字典都使用点分隔符就足够了,如果您想从多层字典中初始化它,也可以尝试实现__init__


哎呀,@ Kugel的答案是相似的。
tdihp

1
tdihp,我仍然喜欢您的回答,因为我理解得更快-它具有实际的代码。
yigal 2014年

1
+1为实际代码。但是@Kugel使用Bunch的建议也很好。
丹妮德2014年

我认为有必要通过将嵌入这个函数里面def docdict(name):前,然后`如果isinstance(姓名,字典):返回DotDict(名)的回报名`
丹尼尔Moskovich的

很好的简单示例。我对此进行了扩展,以便像@DanielMoskovich一样轻松地链接嵌套字典,但也正确返回了int,string等叶节点,如果找不到,则返回nullclass dotdict(dict): def __getattr__(self, name): if name not in self: return None elif type(self[name]) is dict: return JsonDot(self[name]) else: return self[name]
D Sievers

11

别。属性访问和索引编制在Python中是分开的,您不希望它们执行相同的操作。namedtuple如果您有一些应该具有可访问属性的东西,并使用[]表示法从字典中获取一项,则创建一个类(可能是由制成的类)。


感谢你的回答。但是看看我也问过的这个问题:stackoverflow.com/questions/2352252/… 这似乎是一个好主意,.而不是[]用来访问Mako模板中的复杂数据结构。
bodacydo 2010年

2
我可以看到一个用例。实际上,我是在几周前完成的。就我而言,我想要一个可以使用点表示法访问属性的对象。我发现简单地从dict继承非常容易,因此我获得了所有dict内置的功能,但是此对象的公共接口使用点符号(本质上是一些静态数据的只读接口)。我的用户使用'foo.bar'比使用'foo [“ bar”]'更快乐,并且我很高兴可以支持dict数据类型的功能。
布赖恩·奥克利

10
您已经知道Python的良好风格:我们是在告诉您,不要假装dict的值是属性。这是不好的做法。例如,如果要存储与dict的现有属性同名的值,例如“ items”或“ get”或“ pop”,该怎么办?可能有些混乱。所以不要这样做!
拉里·黑斯廷斯

5
糟糕,我忘记了“商品”,“获取”或“流行”等属性。感谢您提出这个重要的例子!
bodacydo 2010年

5
@Gabe,已经很长时间了...但是我认为这是值得一提的。它“在JS中不够好”:“在JS中足够可怕”。当您存储与原型链中其他重要属性同名的键/属性时,它会变得很有趣。
bgusach 2014年

11

如果要腌制修改后的字典,则需要在上述答案中添加一些状态方法:

class DotDict(dict):
    """dot.notation access to dictionary attributes"""
    def __getattr__(self, attr):
        return self.get(attr)
    __setattr__= dict.__setitem__
    __delattr__= dict.__delitem__

    def __getstate__(self):
        return self

    def __setstate__(self, state):
        self.update(state)
        self.__dict__ = self

感谢您对酸洗的评论。这个错误让我发疯,只意识到那是因为这个问题!
沙格鲁

当您使用copy.deepcopy时也会发生。此添加是必需的。
user1363990

简化:__getattr__ = dict.get
martineau

9

以库格尔(Kugel)的答案为基础,并考虑迈克·格雷厄姆(Mike Graham)的警告语,如果我们做包装纸怎么办?

class DictWrap(object):
  """ Wrap an existing dict, or create a new one, and access with either dot 
    notation or key lookup.

    The attribute _data is reserved and stores the underlying dictionary.
    When using the += operator with create=True, the empty nested dict is 
    replaced with the operand, effectively creating a default dictionary
    of mixed types.

    args:
      d({}): Existing dict to wrap, an empty dict is created by default
      create(True): Create an empty, nested dict instead of raising a KeyError

    example:
      >>>dw = DictWrap({'pp':3})
      >>>dw.a.b += 2
      >>>dw.a.b += 2
      >>>dw.a['c'] += 'Hello'
      >>>dw.a['c'] += ' World'
      >>>dw.a.d
      >>>print dw._data
      {'a': {'c': 'Hello World', 'b': 4, 'd': {}}, 'pp': 3}

  """

  def __init__(self, d=None, create=True):
    if d is None:
      d = {}
    supr = super(DictWrap, self)  
    supr.__setattr__('_data', d)
    supr.__setattr__('__create', create)

  def __getattr__(self, name):
    try:
      value = self._data[name]
    except KeyError:
      if not super(DictWrap, self).__getattribute__('__create'):
        raise
      value = {}
      self._data[name] = value

    if hasattr(value, 'items'):
      create = super(DictWrap, self).__getattribute__('__create')
      return DictWrap(value, create)
    return value

  def __setattr__(self, name, value):
    self._data[name] = value  

  def __getitem__(self, key):
    try:
      value = self._data[key]
    except KeyError:
      if not super(DictWrap, self).__getattribute__('__create'):
        raise
      value = {}
      self._data[key] = value

    if hasattr(value, 'items'):
      create = super(DictWrap, self).__getattribute__('__create')
      return DictWrap(value, create)
    return value

  def __setitem__(self, key, value):
    self._data[key] = value

  def __iadd__(self, other):
    if self._data:
      raise TypeError("A Nested dict will only be replaced if it's empty")
    else:
      return other


6

我喜欢Munch,它在点访问之外还提供了许多方便的选项。

进口午餐

temp_1 = {'person':{'fname':'senthil','lname':'ramalingam'}}

dict_munch = munch.munchify(temp_1)

dict_munch.person.fname


6

最近,我遇到了“ Box ”库,它做同样的事情。

安装命令: pip install python-box

例:

from box import Box

mydict = {"key1":{"v1":0.375,
                    "v2":0.625},
          "key2":0.125,
          }
mydict = Box(mydict)

print(mydict.key1.v1)

我发现它比其他现有的库(例如dotmap)更有效,如点阵图,当嵌套的字典较大时,它们会生成python递归错误。

链接到库和详细信息:https : //pypi.org/project/python-box/


5

使用__getattr__非常简单,可在Python 3.4.3中使用

class myDict(dict):
    def __getattr__(self,val):
        return self[val]


blockBody=myDict()
blockBody['item1']=10000
blockBody['item2']="StackOverflow"
print(blockBody.item1)
print(blockBody.item2)

输出:

10000
StackOverflow

4

语言本身不支持此功能,但有时这仍然是有用的要求。除了Bunch食谱之外,您还可以编写一些小方法,该方法可以使用点分字符串来访问字典:

def get_var(input_dict, accessor_string):
    """Gets data from a dictionary using a dotted accessor-string"""
    current_data = input_dict
    for chunk in accessor_string.split('.'):
        current_data = current_data.get(chunk, {})
    return current_data

这将支持以下内容:

>> test_dict = {'thing': {'spam': 12, 'foo': {'cheeze': 'bar'}}}
>> output = get_var(test_dict, 'thing.spam.foo.cheeze')
>> print output
'bar'
>>

4

为了建立epool的答案,此版本允许您通过点运算符访问内部的所有dict:

foo = {
    "bar" : {
        "baz" : [ {"boo" : "hoo"} , {"baba" : "loo"} ]
    }
}

例如,foo.bar.baz[1].babareturn "loo"

class Map(dict):
    def __init__(self, *args, **kwargs):
        super(Map, self).__init__(*args, **kwargs)
        for arg in args:
            if isinstance(arg, dict):
                for k, v in arg.iteritems():
                    if isinstance(v, dict):
                        v = Map(v)
                    if isinstance(v, list):
                        self.__convert(v)
                    self[k] = v

        if kwargs:
            for k, v in kwargs.iteritems():
                if isinstance(v, dict):
                    v = Map(v)
                elif isinstance(v, list):
                    self.__convert(v)
                self[k] = v

    def __convert(self, v):
        for elem in xrange(0, len(v)):
            if isinstance(v[elem], dict):
                v[elem] = Map(v[elem])
            elif isinstance(v[elem], list):
                self.__convert(v[elem])

    def __getattr__(self, attr):
        return self.get(attr)

    def __setattr__(self, key, value):
        self.__setitem__(key, value)

    def __setitem__(self, key, value):
        super(Map, self).__setitem__(key, value)
        self.__dict__.update({key: value})

    def __delattr__(self, item):
        self.__delitem__(item)

    def __delitem__(self, key):
        super(Map, self).__delitem__(key)
        del self.__dict__[key]

1
Python的3:更换iteritems()items()xrange()range()
sasawatc

3
def dict_to_object(dick):
    # http://stackoverflow.com/a/1305663/968442

    class Struct:
        def __init__(self, **entries):
            self.__dict__.update(entries)

    return Struct(**dick)

如果决定永久将其转换dict为对象,则应该这样做。您可以在访问之前创建一个一次性对象。

d = dict_to_object(d)

def attr(** kwargs):o = lambda:无o .__ dict __。update(** kwargs)返回o
throws_exceptions_at_you

2

我最终都尝试了AttrDict Bunch库,发现它们是我使用速度减慢的方法。经过一个朋友和我的研究,我们发现编写这些库的主要方法导致该库通过嵌套对象积极地递归并在整个字典对象中进行复制。考虑到这一点,我们进行了两个关键更改。1)我们使属性延迟加载; 2)我们创建轻量级代理对象的副本,而不是创建字典对象的副本。这是最终的实现。使用此代码的性能提升令人难以置信。使用AttrDict或Bunch时,仅这两个库分别消耗了我的请求时间的1/2和1/3(什么!?)。这段代码将时间减少到几乎没有(在0.5ms范围内)。当然,这取决于您的需求,但是如果您在代码中大量使用此功能,

class DictProxy(object):
    def __init__(self, obj):
        self.obj = obj

    def __getitem__(self, key):
        return wrap(self.obj[key])

    def __getattr__(self, key):
        try:
            return wrap(getattr(self.obj, key))
        except AttributeError:
            try:
                return self[key]
            except KeyError:
                raise AttributeError(key)

    # you probably also want to proxy important list properties along like
    # items(), iteritems() and __len__

class ListProxy(object):
    def __init__(self, obj):
        self.obj = obj

    def __getitem__(self, key):
        return wrap(self.obj[key])

    # you probably also want to proxy important list properties along like
    # __iter__ and __len__

def wrap(value):
    if isinstance(value, dict):
        return DictProxy(value)
    if isinstance(value, (tuple, list)):
        return ListProxy(value)
    return value

通过https://stackoverflow.com/users/704327/michael-merickel查看此处的原始实现。

还要注意的另一件事是,此实现非常简单,并没有实现您可能需要的所有方法。您需要根据需要在DictProxy或ListProxy对象上编写这些内容。


0

我想将自己的解决方案付诸实践:

https://github.com/skorokithakis/jsane

它使您可以将JSON解析为可以访问的内容with.attribute.lookups.like.this.r(),主要是因为在开始使用JSON 之前我还没有看到这个答案。


Python犯了几个令人讨厌的简单设计错误,KeyError其中之一就是引发错误,当访问一个不存在的键时,它所要做的就是返回None类似于JS行为的返回值。我非常喜欢阅读和写作中的自动生存。您的图书馆最接近理想。
nehem

0

不是直接回答OP的问题,而是受到某些人的启发,也许对某些人有用。.我已经使用内部__dict__方法创建了基于对象的解决方案(绝不优化代码)

payload = {
    "name": "John",
    "location": {
        "lat": 53.12312312,
        "long": 43.21345112
    },
    "numbers": [
        {
            "role": "home",
            "number": "070-12345678"
        },
        {
            "role": "office",
            "number": "070-12345679"
        }
    ]
}


class Map(object):
    """
    Dot style access to object members, access raw values
    with an underscore e.g.

    class Foo(Map):
        def foo(self):
            return self.get('foo') + 'bar'

    obj = Foo(**{'foo': 'foo'})

    obj.foo => 'foobar'
    obj._foo => 'foo'

    """

    def __init__(self, *args, **kwargs):
        for arg in args:
            if isinstance(arg, dict):
                for k, v in arg.iteritems():
                    self.__dict__[k] = v
                    self.__dict__['_' + k] = v

        if kwargs:
            for k, v in kwargs.iteritems():
                self.__dict__[k] = v
                self.__dict__['_' + k] = v

    def __getattribute__(self, attr):
        if hasattr(self, 'get_' + attr):
            return object.__getattribute__(self, 'get_' + attr)()
        else:
            return object.__getattribute__(self, attr)

    def get(self, key):
        try:
            return self.__dict__.get('get_' + key)()
        except (AttributeError, TypeError):
            return self.__dict__.get(key)

    def __repr__(self):
        return u"<{name} object>".format(
            name=self.__class__.__name__
        )


class Number(Map):
    def get_role(self):
        return self.get('role')

    def get_number(self):
        return self.get('number')


class Location(Map):
    def get_latitude(self):
        return self.get('lat') + 1

    def get_longitude(self):
        return self.get('long') + 1


class Item(Map):
    def get_name(self):
        return self.get('name') + " Doe"

    def get_location(self):
        return Location(**self.get('location'))

    def get_numbers(self):
        return [Number(**n) for n in self.get('numbers')]


# Tests

obj = Item({'foo': 'bar'}, **payload)

assert type(obj) == Item
assert obj._name == "John"
assert obj.name == "John Doe"
assert type(obj.location) == Location
assert obj.location._lat == 53.12312312
assert obj.location._long == 43.21345112
assert obj.location.latitude == 54.12312312
assert obj.location.longitude == 44.21345112

for n in obj.numbers:
    assert type(n) == Number
    if n.role == 'home':
        assert n.number == "070-12345678"
    if n.role == 'office':
        assert n.number == "070-12345679"

0

获得点访问(而不是数组访问)的一种简单方法是在Python中使用普通对象。像这样:

class YourObject:
    def __init__(self, *args, **kwargs):
        for k, v in kwargs.items():
            setattr(self, k, v)

...并像这样使用它:

>>> obj = YourObject(key="value")
>>> print(obj.key)
"value"

...将其转换为字典:

>>> print(obj.__dict__)
{"key": "value"}

0

此解决方案是对epool提供的解决方案的改进,以解决OP以一致方式访问嵌套dict的要求。epool的解决方案不允许访问嵌套字典。

class YAMLobj(dict):
    def __init__(self, args):
        super(YAMLobj, self).__init__(args)
        if isinstance(args, dict):
            for k, v in args.iteritems():
                if not isinstance(v, dict):
                    self[k] = v
                else:
                    self.__setattr__(k, YAMLobj(v))


    def __getattr__(self, attr):
        return self.get(attr)

    def __setattr__(self, key, value):
        self.__setitem__(key, value)

    def __setitem__(self, key, value):
        super(YAMLobj, self).__setitem__(key, value)
        self.__dict__.update({key: value})

    def __delattr__(self, item):
        self.__delitem__(item)

    def __delitem__(self, key):
        super(YAMLobj, self).__delitem__(key)
        del self.__dict__[key]

有了这一堂课,您现在可以执行以下操作:A.B.C.D


0

这也适用于嵌套字典,并确保稍后附加的字典具有相同的行为:

class DotDict(dict):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Recursively turn nested dicts into DotDicts
        for key, value in self.items():
            if type(value) is dict:
                self[key] = DotDict(value)

    def __setitem__(self, key, item):
        if type(item) is dict:
            item = DotDict(item)
        super().__setitem__(key, item)

    __setattr__ = __setitem__
    __getattr__ = dict.__getitem__

0

@ derek73的答案非常简洁,但是不能被腌制或(深度)复制,并且返回None因缺少键。下面的代码解决了这个问题。

编辑:我没有看到上面的答案完全相同的点(已投票)。我将答案留在这里以供参考。

class dotdict(dict):
    __setattr__ = dict.__setitem__
    __delattr__ = dict.__delitem__

    def __getattr__(self, name):
        try:
            return self[name]
        except KeyError:
            raise AttributeError(name)

-1

一种精致的解决方案

class DotDict(dict):

    __setattr__ = dict.__setitem__
    __delattr__ = dict.__delitem__

    def __getattr__(self, key):

        def typer(candidate):
            if isinstance(candidate, dict):
                return DotDict(candidate)

            if isinstance(candidate, str):  # iterable but no need to iter
                return candidate

            try:  # other iterable are processed as list
                return [typer(item) for item in candidate]
            except TypeError:
                return candidate

            return candidate

        return typer(dict.get(self, key))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.