如何使用点“.”访问字典成员?
如何使 Python 字典成员可以通过点“.”访问?
例如,我不想编写 mydict['val']
,而是编写 mydict.val
。
我也想以这种方式访问嵌套字典。例如
mydict.mydict2.val
将参考
mydict = { 'mydict2': { 'val': ... } }
How do I make Python dictionary members accessible via a dot "."?
For example, instead of writing mydict['val']
, I'd like to write mydict.val
.
Also I'd like to access nested dicts this way. For example
mydict.mydict2.val
would refer to
mydict = { 'mydict2': { 'val': ... } }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(30)
我一直将其保存在 util 文件中。您也可以将它用作您自己的类中的 mixin。
I've always kept this around in a util file. You can use it as a mixin on your own classes too.
你可以使用我刚刚制作的这个课程来做到这一点。通过此类,您可以像另一个字典(包括 json 序列化)一样使用
Map
对象或使用点表示法。我希望对您有所帮助:使用示例:
You can do it using this class I just made. With this class you can use the
Map
object like another dictionary(including json serialization) or with the dot notation. I hope to help you:Usage examples:
通过
pip
安装dotmap
它可以完成您想要它做的所有事情并子类化
dict
,因此它的操作就像普通的字典一样:除此之外,您可以将其与
dict
对象相互转换:这意味着,如果您要访问的内容已经采用
dict
形式,您可以将其转换为DotMap< /code> 以便于访问:
最后,它会自动创建新的子
DotMap
实例,因此您可以执行以下操作:与 Bunch 的比较
全面披露:我是 DotMap。我创建它是因为
Bunch
缺少这些功能,DotMap
创建,这可以节省时间并在您有 大量层次结构,并将所有子dict
实例递归地转换为DotMap
dict
构建Install
dotmap
viapip
It does everything you want it to do and subclasses
dict
, so it operates like a normal dictionary:On top of that, you can convert it to and from
dict
objects:This means that if something you want to access is already in
dict
form, you can turn it into aDotMap
for easy access:Finally, it automatically creates new child
DotMap
instances so you can do things like this:Comparison to Bunch
Full disclosure: I am the creator of the DotMap. I created it because
Bunch
was missing these featuresDotMap
creation, which saves time and makes for cleaner code when you have a lot of hierarchydict
and recursively converting all childdict
instances toDotMap
使用SimpleNamespace:
Use
SimpleNamespace
:从 dict 派生并实现
__getattr__
和__setattr__
。或者您可以使用 Bunch 非常相似。
我认为不可能对内置字典类进行猴子修补。
Derive from dict and and implement
__getattr__
and__setattr__
.Or you can use Bunch which is very similar.
I don't think it's possible to monkeypatch built-in dict class.
Fabric 有一个非常好的、最小的实现。扩展它以允许嵌套访问,我们可以使用
defaultdict
,结果看起来像这样:按如下方式使用它:
这详细说明了 Kugel 的回答“源自dict 并实现
__getattr__
和__setattr__
”。 现在你知道怎么做了!Fabric has a really nice, minimal implementation. Extending that to allow for nested access, we can use a
defaultdict
, and the result looks something like this:Make use of it as follows:
That elaborates a bit on Kugel's answer of "Derive from dict and and implement
__getattr__
and__setattr__
". Now you know how!我尝试过:
您也可以尝试
__getattribute__
。让每个字典都是 dotdict 类型就足够了,如果你想从多层字典初始化它,也可以尝试实现
__init__
。I tried this:
you can try
__getattribute__
too.make every dict a type of dotdict would be good enough, if you want to init this from a multi-layer dict, try implement
__init__
too.我最近遇到了 'Box' 库,它做了同样的事情。
安装命令:
pip install python-box
示例:
我发现它比其他现有库(如 dotmap)更有效,当你有大型嵌套字典时,它会生成 python 递归错误。
链接到库和详细信息: https://pypi.org/project/python-box/
I recently came across the 'Box' library which does the same thing.
Installation command :
pip install python-box
Example:
I found it to be more effective than other existing libraries like dotmap, which generate python recursion error when you have large nested dicts.
link to library and details: https://pypi.org/project/python-box/
不。在 Python 中,属性访问和索引是不同的事情,您不应该希望它们执行相同的操作。如果您有一些应该具有可访问属性并使用
[]
表示法从字典中获取项目的内容,请创建一个类(可能是由namedtuple
创建的类)。Don't. Attribute access and indexing are separate things in Python, and you shouldn't want them to perform the same. Make a class (possibly one made by
namedtuple
) if you have something that should have accessible attributes and use[]
notation to get an item from a dict.如果你想腌制修改后的字典,你需要在上面的答案中添加一些状态方法:
If you want to pickle your modified dictionary, you need to add few state methods to above answers:
您可以使用 SimpleNamespace 来实现这一点
You can achieve this using SimpleNamespace
为了构建 epool 的答案,此版本允许您通过点运算符访问内部的任何字典:
例如,
foo.bar.baz[1].baba
返回“loo”
。To build upon epool's answer, this version allows you to access any dict inside via the dot operator:
For instance,
foo.bar.baz[1].baba
returns"loo"
.根据 Kugel 的回答并考虑到 Mike Graham 的警告,如果我们制作一个包装器会怎么样?
Building on Kugel's answer and taking Mike Graham's words of caution into consideration, what if we make a wrapper?
使用
__getattr__
,非常简单,适用于Python 3.4.3
输出:
Use
__getattr__
, very simple, works inPython 3.4.3
Output:
我喜欢 Munch,它在点访问之上提供了很多方便的选项。
I like the Munch and it gives lot of handy options on top of dot access.
语言本身不支持这一点,但有时这仍然是一个有用的要求。除了 Bunch 配方之外,您还可以编写一个小方法,可以使用点分字符串访问字典:
这将支持如下内容:
The language itself doesn't support this, but sometimes this is still a useful requirement. Besides the Bunch recipe, you can also write a little method which can access a dictionary using a dotted string:
which would support something like this:
我不喜欢在(超过)10 年的火灾中添加另一根木头,但我也会查看 < code>dotwiz 库,我最近发布了 - 实际上就在今年。
这是一个相对较小的库,在 get(访问)和 set(创建)次数方面也表现得非常好 在基准测试中,至少与其他替代方案相比。
通过
pip
安装dotwiz
它会做你想要它做的一切,并子类化
dict
,所以它的操作就像一个普通的字典:最重要的是,您可以将其与
dict
对象相互转换:这意味着,如果您要访问的内容已经采用
dict
形式,您可以将其转换为DotWiz< /code> 以便于访问:
最后,我正在处理的一些令人兴奋的事情是现有的功能请求 这样它就会自动创建新的子
DotWiz
实例,这样您就可以执行以下操作:与
dotmap
的比较我添加了与
dotmap
下面。首先,使用
pip
安装这两个库:我出于基准目的编写了以下代码:
结果,在我的 M1 Mac 上运行 Python 3.10:
I dislike adding another log to a (more than) 10-year old fire, but I'd also check out the
dotwiz
library, which I've recently released - just this year actually.It's a relatively tiny library, which also performs really well for get (access) and set (create) times in benchmarks, at least as compared to other alternatives.
Install
dotwiz
viapip
It does everything you want it to do and subclasses
dict
, so it operates like a normal dictionary:On top of that, you can convert it to and from
dict
objects:This means that if something you want to access is already in
dict
form, you can turn it into aDotWiz
for easy access:Finally, something exciting I am working on is an existing feature request so that it automatically creates new child
DotWiz
instances so you can do things like this:Comparison with
dotmap
I've added a quick and dirty performance comparison with
dotmap
below.First, install both libraries with
pip
:I came up with the following code for benchmark purposes:
Results, on my M1 Mac, running Python 3.10:
我最终尝试了 AttrDict 和 Bunch 库,发现它们对我的使用来说速度很慢。在我和一个朋友研究之后,我们发现编写这些库的主要方法会导致库积极地递归嵌套对象并始终复制字典对象。考虑到这一点,我们做出了两项关键改变。 1) 我们使属性延迟加载 2) 我们不创建字典对象的副本,而是创建轻量级代理对象的副本。这是最终的实现。使用这段代码的性能提升是令人难以置信的。当使用 AttrDict 或 Bunch 时,这两个库分别消耗了我请求时间的 1/2 和 1/3(什么!?)。这段代码将时间减少到几乎为零(在 0.5 毫秒的范围内)。这当然取决于您的需求,但是如果您在代码中大量使用此功能,那么一定要使用这样简单的东西。
请参阅此处,作者:https://stackoverflow.com/users/704327/michael-merickel。
另一件需要注意的事情是,这个实现非常简单,并且没有实现您可能需要的所有方法。您需要根据需要在 DictProxy 或 ListProxy 对象上编写这些内容。
I ended up trying BOTH the AttrDict and the Bunch libraries and found them to be way to slow for my uses. After a friend and I looked into it, we found that the main method for writing these libraries results in the library aggressively recursing through a nested object and making copies of the dictionary object throughout. With this in mind, we made two key changes. 1) We made attributes lazy-loaded 2) instead of creating copies of a dictionary object, we create copies of a light-weight proxy object. This is the final implementation. The performance increase of using this code is incredible. When using AttrDict or Bunch, these two libraries alone consumed 1/2 and 1/3 respectively of my request time(what!?). This code reduced that time to almost nothing(somewhere in the range of 0.5ms). This of course depends on your needs, but if you are using this functionality quite a bit in your code, definitely go with something simple like this.
See the original implementation here by https://stackoverflow.com/users/704327/michael-merickel.
The other thing to note, is that this implementation is pretty simple and doesn't implement all of the methods you might need. You'll need to write those as required on the DictProxy or ListProxy objects.
这也适用于嵌套字典,并确保稍后附加的字典行为相同:
This also works with nested dicts and makes sure that dicts which are appended later behave the same:
用于字典、列表、字典列表和列表字典的无限级别嵌套。
它还支持酸洗
这是这个答案的扩展。
For infinite levels of nesting of dicts, lists, lists of dicts, and dicts of lists.
It also supports pickling
This is an extension of this answer.
如果您决定永久将该
dict
转换为对象,则应该这样做。您可以在访问之前创建一个一次性对象。If one decides to permanently convert that
dict
to object this should do. You can create a throwaway object just before accessing.该解决方案是对 epool 提供的解决方案的改进,旨在满足 OP 以一致方式访问嵌套字典的要求。 epool 的解决方案不允许访问嵌套字典。
有了这个类,人们现在可以做类似的事情:
ABCD
。This solution is a refinement upon the one offered by epool to address the requirement of the OP to access nested dicts in a consistent manner. The solution by epool did not allow for accessing nested dicts.
With this class, one can now do something like:
A.B.C.D
.使用
namedtuple
允许点访问。它就像一个轻量级对象,也具有元组的属性。
它允许定义属性并使用点运算符访问它们。
使用点运算符访问
使用元组索引访问
但请记住这是一个元组; 不是字典。因此下面的代码将给出错误
参考: namedtuple
Using
namedtuple
allows dot access.It is like a lightweight object which also has the properties of a tuple.
It allows to define properties and access them using the dot operator.
Access using dot operator
Access using tuple indices
But remember this is a tuple; not a dict. So the below code will give error
Refer: namedtuple
这是一个老问题,但我最近发现 sklearn 有一个可通过按键访问的实现版本 dict,即 Bunch
https://scikit-learn。 org/stable/modules/ generated/sklearn.utils.Bunch.html#sklearn.utils.Bunch
It is an old question but I recently found that
sklearn
has an implemented versiondict
accessible by key, namelyBunch
https://scikit-learn.org/stable/modules/generated/sklearn.utils.Bunch.html#sklearn.utils.Bunch
最简单的解决方案。
定义一个类,其中仅包含 pass 语句。为此类创建对象并使用点表示法。
Simplest solution.
Define a class with only pass statement in it. Create object for this class and use dot notation.
获得点访问(但不是数组访问)的一种简单方法是在 Python 中使用普通对象。像这样:
...并像这样使用它:
...将其转换为字典:
One simple way to get dot access (but not array access), is to use a plain object in Python. Like this:
...and use it like this:
... to convert it to a dict:
@derek73的答案非常简洁,但它不能被腌制,也不能(深度)复制,并且它返回
None
缺少钥匙。下面的代码修复了这个问题。编辑:我没有看到上面的答案解决了完全相同的问题(已投票)。我把答案留在这里供参考。
The answer of @derek73 is very neat, but it cannot be pickled nor (deep)copied, and it returns
None
for missing keys. The code below fixes this.Edit: I did not see the answer above that addresses the exact same point (upvoted). I'm leaving the answer here for reference.
我只需要使用点路径字符串访问字典,所以我想出了:
I just needed to access a dictionary using a dotted path string, so I came up with:
kaggle_environments 使用的实现是一个名为
structify
的函数。这对于在 连接X
The implemention used by kaggle_environments is a function called
structify
.This may be useful for testing AI simulation agents in games like ConnectX
最佳且完整的实施
测试:
Best and complete implementation
Test: