yydict属性字典-一种更加方便的方式访问字典
问题引入
这篇文章是想介绍 最近在使用字典的一种困惑. 我希望通过少写几个字符来访问 python中字典这种数据结构.
比如这个例子:
person = {'name': 'frank','age': 18,'hobby': 'swimming'
}
在python中字典的定义 如上面的例子, 如果我希望访问 person的姓名,我可以使用 pseron['name']
, 或者使用person.get('name')
这两种方式. 这种访问方式本身也没有什么问题, 只是觉得这样访问比较繁琐, 第一种方式我要写一组 中括号,一组引号在加上name
来访问这个字典中的数据.
这让我想起在 JavaScript 语言中,对象访问数据的方式.
这样的访问方式 是不是 更加好一些呢? 这样是不是更加节省时间呢? 特别是遇到 嵌套字典的情况,只需要通过点操作符就可以访问字典中的元素 是不是很方便呢?
使用样例
from yydict import YYDictperson = {'name': 'frank','age': 18,'hobby': 'swimming'
}if __name__ == '__main__':person = YYDict(person)print(person.name) # frankprint(person.age) # 18
我希望这样的方式进行访问字典中的数据, 这样就会比较方便了, 如果遇到嵌套的情况也是可以的.
from yydict import YYDictperson_info = {'Frank': {'phone': '118-1234-5678','email': 'john@example.com','address': {'street': '123 Main St','city': 'New York',}},'Jane': {'phone': '555-5678','email': 'jane@example.com','address': {'street': '456 Elm St','city': 'San Francisco',}}
}if __name__ == '__main__':person_info = YYDict(person_info)print(person_info.Frank.phone) # 118-1234-5678print(person_info.Frank.address) # {'street': '123 Main St', 'city': 'New York'} print(person_info.Frank.address.city) # New Yorkprint(person_info.Jane.address.city) # San Francisco
上面的字典的访问方式是不是 非常方便呢?
好了今天它来了, 我们可以写一个子类继承dict
,可以通过实现 Python 魔术方法 __setattr__
, __getattr__
在字典初始化的时候,把属性顺便也赋值一下.
其实写个类 主要是前端时间在获取一个后端接口数据的时候 返回json 的数据层级特别的深,每次写这个我都很崩溃.
示例数据如下:
data = {"code":20000,"item":[{"content":{},"element_type":"xxx","id":"xxxxx","page_num":[]},{"content":{},"tables":[{"tables":[{"cells":{},"extra_info":{},"mapper":[],"mask":[],"text_matrix":[["12 月 25日(周一)","12 月 26 日(周二)","12 月 27 日(周三)","12 月 28 日(周四)","12 月 29日(周五)","12 月 30日(周六)","12 月 31 日(周日)"]]}]}],"element_type":"paragraph","id":"xxxxxxxxx","page_num":[]}],"status":200
}
我希望获取 text_matrix
里面的信息 这里有4层的嵌套 我才能访问到, 就要写很多多余的中括号来访问到数据.
有了 yydict 就很方便了.
from yydict import YYDictres_data = YYDict(data)matrix = res_data.item[1].tables[0].tables[0].text_matrix
print(matrix)
只需要这样访问就可以了,是不是很方便呢?
注意事项
注意: 如果字典中的key 的名字 和dict 的默认方法名称一样,此时不做任何处理.
data = {"code": 20000,"items": [1,2,3]}res_data = YYDict(data)print(res_data.items) # <built-in method items of YYDict object at 0x10f080590>
print(res_data['items']) # [1, 2, 3]
我们知道 dict 中有一个内置的方法名items
,如果此时恰巧的是,字典中的key名称和这个名称一样, 那么此时就老实地 使用 中括号的方式访问吧. 因为不能把原理字典中内置的属性覆盖掉,这样做方式也不太妥当.
这个类我已经写好了,具体的链接在这里yydict repo ,大家可以通过 pip
安装使用, 在使用的过程中,遇到什么bug,欢迎给我提issue ,我会尽快解决.