我如何使Python字典成员访问通过点“。”?

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

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

mydict.mydict2.val 

会提到

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

当前回答

使用SimpleNamespace:

>>> from types import SimpleNamespace   
>>> d = dict(x=[1, 2], y=['a', 'b'])
>>> ns = SimpleNamespace(**d)
>>> ns.x
[1, 2]
>>> ns
namespace(x=[1, 2], y=['a', 'b'])

其他回答

派生自dict和并实现__getattr__和__setattr__。

或者你也可以用Bunch,非常相似。

我不认为这是可能的monkeypatch内置字典类。

您可以使用SimpleNamespace来实现这一点

from types import SimpleNamespace
# Assign values
args = SimpleNamespace()
args.username = 'admin'

# Retrive values
print(args.username)  # output: admin

如果你想pickle你修改后的字典,你需要添加几个状态方法到上面的答案:

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

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

这详细阐述了Kugel的回答“从dict和派生并实现__getattr__和__setattr__”。现在你知道怎么做了!

这是一个老问题,但我最近发现sklearn有一个可通过键访问的实现版本字典,即Bunch https://scikit-learn.org/stable/modules/generated/sklearn.utils.Bunch.html#sklearn.utils.Bunch