V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
jakeyfly
V2EX  ›  问与答

Python 有没有库是可以把字典像属性那样操作的?

  •  
  •   jakeyfly · 2018-06-01 20:56:02 +08:00 · 3029 次点击
    这是一个创建于 2155 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如 dict_1 = {"a":1} 直接 dict_1.a 就会显示 1

    我原来自己写了一个简单的,感觉功能不行,要赋值还要重写__setarrt__ 太复杂 怕弄错,有没有现成的库

    16 条回复    2018-06-02 13:10:47 +08:00
    niubee1
        1
    niubee1  
       2018-06-01 21:18:33 +08:00
    看看老的 tornado 的代码, 记得最早的版本里封装了一个, 很简单, 十几行代码就搞定了
    coffeSlider
        2
    coffeSlider  
       2018-06-01 21:53:36 +08:00 via Android
    我的做法是,写个 class 设置__dict__ 为你的 dict
    maemual
        3
    maemual  
       2018-06-01 21:56:31 +08:00
    ObjectDict
    jatsz
        4
    jatsz  
       2018-06-01 22:23:05 +08:00   ❤️ 7
    class AttrDict(dict):
    __getattr__ = dict.__getitem__
    __setattr__ = dict.__setitem__

    dict1 = AttrDict(dict_1)

    dict1.a == 1
    bravecarrot
        5
    bravecarrot  
       2018-06-01 22:32:06 +08:00
    写了一个贼丑的
    ```Python

    class Duck(dict):
    def __init__(self, *args, **kw):
    return super(Duck, self).__init__(self, *args, **kw)

    def __getattr__(self, key):
    try:
    return self[key]
    except KeyError as e:
    print e

    def __setattr__(self, *args, **kw):
    object.__setattr__(self, *args, **kw)
    for k, v in self.__dict__.items():
    if k not in self.keys():
    self[k] = v


    if __name__ == "__main__":
    s = Duck()
    # as a dict
    s['a'] = 1
    print s.a
    # set and get attribute
    s.c = [1,3]
    print s.c
    print s['c']
    ```
    glasslion
        6
    glasslion  
       2018-06-01 22:51:45 +08:00   ❤️ 3
    just1
        7
    just1  
       2018-06-01 22:54:09 +08:00 via Android   ❤️ 1
    pip install python-box
    jakeyfly
        8
    jakeyfly  
    OP
       2018-06-01 23:42:40 +08:00
    @bravecarrot
    class FrozenDict:
    def __new__(cls, arg):
    if isinstance(arg, abc.Mapping):
    return super().__new__(cls)
    elif isinstance(arg, abc.MutableSequence):
    return [cls(item) for item in arg]
    else:
    return arg

    def __init__(self, mapping):
    self.__data = {}
    for key, val in mapping.items():
    self.__data[key] = val

    def __getattr__(self, name):
    if hasattr(self.__data, name):
    return getattr(self.__data, name)
    else:
    return FrozenDict(self.__data[name])

    这我以前从书上学的,只读还行,要写入就要重写__setattr__ 不太会
    jakeyfly
        9
    jakeyfly  
    OP
       2018-06-01 23:43:04 +08:00
    @glasslion 这个强无敌
    bravecarrot
        10
    bravecarrot  
       2018-06-01 23:56:34 +08:00 via iPhone
    @jakeyfly 我觉得 @jatsz 的已经很强了

    但是我的也能用呀(大笑)
    jakeyfly
        11
    jakeyfly  
    OP
       2018-06-02 00:29:06 +08:00
    @bravecarrot 大佬你这个好像不能读嵌套的呀,哈
    jakeyfly
        12
    jakeyfly  
    OP
       2018-06-02 00:30:15 +08:00
    @jatsz 大佬 你这是高端猴子补丁吗
    param
        13
    param  
       2018-06-02 00:57:50 +08:00 via Android
    秒变 JS
    dacapoday
        14
    dacapoday  
       2018-06-02 08:40:36 +08:00 via iPhone
    easydict
    jatsz
        15
    jatsz  
       2018-06-02 10:00:06 +08:00
    @jakeyfly
    这个是挺猴的,记不得在哪里看到的,不过也不能解决嵌套问题。

    在项目中使用的是这个版本,能解决嵌套的问题:

    class AttrDict(dict):
    """
    A class to convert a nested Dictionary into an object with key-values
    that are accessible using attribute notation (AttrDict.attribute) instead of
    key notation (Dict["key"]). This class recursively sets Dicts to objects,
    allowing you to recurse down nested dicts (like: AttrDict.attr.attr)
    """

    # Inspired by:
    # http://stackoverflow.com/a/14620633/1551810
    # http://databio.org/posts/python_AttributeDict.html

    def __init__(self, iterable, **kwargs):
    super(AttrDict, self).__init__(iterable, **kwargs)
    for key, value in iterable.items():
    if isinstance(value, dict):
    self.__dict__[key] = AttrDict(value)
    else:
    self.__dict__[key] = value
    jakeyfly
        16
    jakeyfly  
    OP
       2018-06-02 13:10:47 +08:00
    @jatsz 嗯 我下了上面那位大佬的库 满好用的,我原先用递归的,经常出问题。还是用别人的轮子好~~~~~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3242 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 00:36 · PVG 08:36 · LAX 17:36 · JFK 20:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.