访问诸如Python中的属性的dict键? [英] Accessing dict keys like an attribute in Python?

查看:456
本文介绍了访问诸如Python中的属性的dict键?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现,将 c> obj.foo 而不是 obj ['foo'] ,所以我写了这个片段:

I find it more conveniant to access dict keys as obj.foo instead of obj['foo'], so I wrote this snippet:

class AttributeDict(dict):
    def __getattr__(self, attr):
        return self[attr]
    def __setattr__(self, attr, value):
        self[attr] = value

但是,我认为必须有一些原因,Python不提供此功能开箱即用。

However, I assume there must be some reason that Python doesn't provide this functionality out of the box. What would be the caveats and pitfalls of accessing dict keys in this manner?

推荐答案

这样做的最好方法是: p>

The best way to do this is:

class AttrDict(dict):
    def __init__(self, *args, **kwargs):
        super(AttrDict, self).__init__(*args, **kwargs)
        self.__dict__ = self

有些职业:


  • 它实际上可以工作!

  • 没有字典类方法被遮蔽(例如 .keys()工作正常)

  • 属性和项目始终保持同步

  • 尝试访问不存在的密钥作为属性正确地引发 AttributeError 而不是 KeyError

  • It actually works!
  • No dictionary class methods are shadowed (e.g. .keys() work just fine)
  • Attributes and items are always in sync
  • Trying to access non-existent key as an attribute correctly raises AttributeError instead of KeyError

缺点:


  • .keys ()工作正常,如果它们被传入的数据覆盖

  • 导致内存泄漏在Python< 2.7.4 / Python3< $ 3.2 $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $没有会员)

  • 对于未开始的,它似乎是纯粹的魔法。

  • Methods like .keys() will not work just fine if they get overwritten by incoming data
  • Causes a memory leak in Python < 2.7.4 / Python3 < 3.2.3
  • Pylint goes bananas with E1123(unexpected-keyword-arg) and E1103(maybe-no-member)
  • For the uninitiated it seems like pure magic.

  • 所有python对象都将其属性存储在名为 __ dict __

  • 没有要求内部字典 __ dict __ 将需要只是一个简单的字母,所以我们可以将 dict()的任何子类分配给内部字典。

  • 在我们的例子中,我们简单地指定我们正在实例化的 AttrDict()实例(因为我们在 __ init __

  • 通过调用 super() __ init __()方法,我们确保它(已经)像一个字典,因为该函数调用所有的字典实例化代码。

  • All python objects internally store their attributes in a dictionary that is named __dict__.
  • There is no requirement that the internal dictionary __dict__ would need to be "just a plain dict", so we can assign any subclass of dict() to the internal dictionary.
  • In our case we simply assign the AttrDict() instance we are instantiating (as we are in __init__).
  • By calling super()'s __init__() method we made sure that it (already) behaves exactly like a dictionary, since that function calls all the dictionary instantiation code.

如cons列表中所述,它将存储的键的命名空间(可能来自任意的和/或不受信任的数据!)与内建dict方法属性的命名空间。例如:

As noted in the "cons" list, this combines the namespace of stored keys (which may come from arbitrary and/or untrusted data!) with the namespace of builtin dict method attributes. For example:

d = AttrDict()
d.update({'items':["jacket", "necktie", "trousers"]})
for k, v in d.items():    # TypeError: 'list' object is not callable
    print "Never reached!"

这篇关于访问诸如Python中的属性的dict键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆