Python使用类似JavaScript的对象——EasyDict(更强大的Dict)

jupiter
2021-01-05 / 0 评论 / 721 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2021年01月05日,已超过1445天没有更新,若内容或图片失效,请留言反馈。

Python使用类似JavaScript的对象——EasyDict(更强大的Dict)

简介

用惯 JavaScript 的人上来用 Python 的字典 dict 会很困惑,为什么只能用[]取属性而不能用.呢?

JavaScript

var data = {
    'class1': {
        'a': {'Chinese': 80},
        '小明': {'Chinese': 90},
    }
};
console.log(data);
console.log(data.class1, data['class1']);
console.log(data.class1.a, data['class1']['a']);
console.log(data.class1.a.Chinese, data['class1']['a']['Chinese']);

console.log(data.class1['小明'].Chinese);  // 混着用

Python 会报错 AttributeError: 'dict' object has no attribute 'xxx'

data = {
    'class1': {
        'a': {'Chinese': 80},
        '小明': {'Chinese': 90},
    }
}
print(data)
print(data.class1, data['class1'])
print(data.class1.a, data['class1']['a'])
print(data.class1.a.Chinese, data['class1']['a']['Chinese'])

print(data.class1['小明'].Chinese)  # 混着用

安装

pip install easydict

PS:可以不安装直接使用源码,仅30行,见文末

初试

from easydict import EasyDict

data = {
    'class1': {
        'a': {'Chinese': 80},
        '小明': {'Chinese': 90},
    }
}
data = EasyDict(data)
print(data)
print(data.class1, data['class1'])
print(data.class1.a, data['class1']['a'])
print(data.class1.a.Chinese, data['class1']['a']['Chinese'])

print(data.class1['小明'].Chinese)  # 混着用
# {'class1': {'a': {'Chinese': 80}, '小明': {'Chinese': 90}}}
# {'a': {'Chinese': 80}, '小明': {'Chinese': 90}} {'a': {'Chinese': 80}, '小明': {'Chinese': 90}}
# {'Chinese': 80} {'Chinese': 80}
# 80 80
# 90
1234567891011121314151617181920
EasyDict` 本质上还是 `Dict
from easydict import EasyDict

data = EasyDict(log=False)
data.debug = True
print(data.items())
# dict_items([('log', False), ('debug', True)])

EasyDict 源码

class EasyDict(dict):
    def __init__(self, d=None, **kwargs):
        if d is None:
            d = {}
        if kwargs:
            d.update(**kwargs)
        for k, v in d.items():
            setattr(self, k, v)
        for k in self.__class__.__dict__.keys():
            if not (k.startswith('__') and k.endswith('__')) and not k in ('update', 'pop'):
                setattr(self, k, getattr(self, k))

    def __setattr__(self, name, value):
        if isinstance(value, (list, tuple)):
            value = [self.__class__(x) if isinstance(x, dict) else x for x in value]
        elif isinstance(value, dict) and not isinstance(value, self.__class__):
            value = self.__class__(value)
        super(EasyDict, self).__setattr__(name, value)
        super(EasyDict, self).__setitem__(name, value)

    __setitem__ = __setattr__

    def update(self, e=None, **f):
        d = e or dict()
        d.update(f)
        for k in d:
            setattr(self, k, d[k])

    def pop(self, k, d=None):
        delattr(self, k)
        return super(EasyDict, self).pop(k, d)
0

评论

博主关闭了当前页面的评论