Python-访问像属性一样的字典键?

发布于 2021-02-02 23:19:21

我发现访问dict键obj.foo而不是更为方便obj['foo'],因此我编写了以下代码段:

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

但是,我认为一定有某些原因导致Python无法立即提供此功能。以这种方式访问​​字典键的注意事项和陷阱是什么?

关注者
0
被浏览
93
1 个回答
  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    最好的方法是:

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

    一些优点:

    • 它实际上有效!
    • 没有字典类方法被遮盖(例如,.keys()工作正常)
    • 属性和项目始终同步
    • 尝试访问不存在的键作为属性正确引发,AttributeError而不是KeyError

    缺点:

    • 如果这样的方法被传入数据覆盖,它们.keys()将无法正常工作
    • 在Python <2.7.4 / Python3 <3.2.3中导致内存泄漏
    • 皮林特(Pylint)E1123(unexpected-keyword-arg)和E1103(maybe-no-member)
    • 对于初学者来说,这似乎是纯魔术。

    简短说明
    - 所有python对象在内部将其属性存储在名为的字典中__dict__。
    - 不需要内部字典__dict__必须是“仅是简单的字典”,因此我们可以将dict()内部字典的任何子类分配给内部字典。
    - 在我们的例子中,我们只需分配要AttrDict()实例化的实例(就像在中一样__init__)。
    - 通过调用super()的__init__()方法,我们可以确保它的行为(已经)完全像字典一样,因为该函数调用了所有字典实例化代码。


    Python不提供现成功能的原因之一

    如“ cons”列表中所述,这将存储键的名称空间(可能来自任意和/或不受信任的数据!)与内置dict方法属性的名称空间结合在一起。例如:

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


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看