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)
评论