Python之深入解析Box为字典添加高级点符号访问特性

举报
Serendipity·y 发表于 2022/02/17 00:34:57 2022/02/17
【摘要】 一、前言 正常情况下,想访问字典中的某个值,都是通过中括号访问,比如: test_dict = {"test": {"imdb stars": 6.7, "length": 104}} print(t...

一、前言

  • 正常情况下,想访问字典中的某个值,都是通过中括号访问,比如:
test_dict = {"test": {"imdb stars": 6.7, "length": 104}}
print(test_dict["test"]["imdb stars"])
# 104

  
 
  • 1
  • 2
  • 3
  • 而通过 Box 模块,可以扩展字典功能,使用点符号访问元素:
from box import Box
movie_box = Box({ "Robin Hood: Men in Tights": { "imdb stars": 6.7, "length": 104 }})
movie_box.Robin_Hood_Men_in_Tights.imdb_stars
# 6.7

  
 
  • 1
  • 2
  • 3
  • 4
  • 可以看到默认情况下转换后,字典键值中的空格被转化为下划线。
  • 安装依赖:
    • Windows 环境 打开 Cmd (开始-运行-CMD);
    • MacOS 环境 打开 Terminal (command + 空格输入Terminal);
    • 如果使用的是 VSCode编辑器或 Pycharm,可以直接使用界面下方的 Terminal:
pip install --upgrade python-box[all]

  
 
  • 1

二、Box 的基本使用

① 生成 Box 并访问

  • 可以像上文中那样,传入一个字典给 Box,生成一个 Box 对象;也可以直接使用参数赋值的方式生成一个 Box 对象:
from box import Box

my_box = Box(funny_movie='Hudson Hawk', best_movie='Kung Fu Panda')
my_box.funny_movie
# 'Hudson Hawk'

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 请记住,任何情况下,往 Box 对象里添加字典或是数组,这些字典或数组都会被转变为 Box 对象:
my_box = Box({"team": {"red": {"leader": "Sarge", "members": []}}})
print(my_box.team.red.leader)
# Sarge

my_box.team.blue = {"leader": "Church", "members": []} 
print(repr(my_box.team.blue))
# <Box: {'leader': 'Church', 'members': []}>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 访问列表中的 Box 对象也非常轻松:
my_box.team.red.members = [
    {"name": "Grif", "rank": "Minor Junior Private Negative First Class"},
    {"name": "Dick Simmons", "rank": "Captain"}
]

print(my_box.team.red.members[0].name)
# Grif

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

② 局限性

  • 字典中有些默认方法,如:clear, copy, fromkeys, get, items, keys, pop, popitem, setdefault, to_dict, update, merge_update, values ,当键值和这些方法名称冲突时,无法使用点符号访问它们。
  • 不过冲突时,依然可以使用传统的字典取值访问它们,例如:
my_box['keys']

  
 
  • 1

③ 合并

  • 要合并两个 Box 对象,只需要通过 merge_update 方法:
from box import Box

box_1 = Box(val={'important_key': 1}) 
box_2 = Box(val={'less_important_key': 2})

box_1.merge_update(box_2)

print(box_1)
# {'val': {'important_key': 1, 'less_important_key': 2}}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 当然,也可以用传统的 update 方法:
from box import Box

box_1 = Box(val={'important_key': 1}) 
box_2 = Box(val={'less_important_key': 2})

box_1.update(box_2)

print(box_1)
# {'val': {'less_important_key': 2}}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

④ 转换为原始列表/字典

  • 如果需要把一个 Box 对象的字典转化为原始字典,.to_dict() 方法就可以实现:
from box import Box

box_1 = Box(val={'important_key': 1}) 

print(box_1)
# {'val': {'less_important_key': 2}}
print(type(box_1))
# <class 'box.box.Box'>
print(type(box_1.to_dict()))
# <class 'dict'>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 如果需要把一个 Box 对象的列表转化为原始列表,可以使用 .to_list() 方法:
from box import BoxList

my_boxlist = BoxList({'item': x} for x in range(10))
# <BoxList: [<Box: {'item': 0}>, <Box: {'item': 1}>, ...

my_boxlist[5].item
# 5

print(type(my_boxlist.to_list()))
# <class 'list'>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

三、导入导出功能

  • Box 对象有一个很方便的功能,就是能够轻松地将 Box 对象导出为 Json / yaml / csv / msgpack 文件:
from box import BoxList

my_boxlist = BoxList({'item': x} for x in range(10))
# <BoxList: [<Box: {'item': 0}>, <Box: {'item': 1}>, ...

my_boxlist.to_json(filename="test.json")
# 在当前文件夹下生成一个 test.json 文件

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 此外,还能接受 Json / yaml / csv / msgpack 文件导入:
new_box = Box.from_json(filename="films.json")

  
 
  • 1
  • 各种类型的文件对应的方法如下:
转换器方法 描述
to_dict 递归地将所有 Box(和 BoxList)对象转换回字典(和列表)
to_json 将 Box 对象另存为 JSON 字符串或使用filename参数写入文件
to_yaml 将 Box 对象另存为 YAML 字符串或使用filename参数写入文件
to_msgpack 将 Box 对象另存为 msgpack 字节或使用filename参数写入文件
to_toml* 将 Box 对象另存为 TOML 字符串或使用filename参数写入文件
to_csv** 将 BoxList 对象另存为 CSV 字符串或使用filename参数写入文件
from_json Classmethod,从一个 JSON 文件或字符串创建一个 Box 对象(所有 Box 参数都可以传递)
from_yaml 类方法,从 YAML 文件或字符串创建一个 Box 对象(所有 Box 参数都可以传递)
from_msgpack Classmethod,从msgpack文件或字节创建一个Box对象(所有Box参数都可以传递)
from_toml* Classmethod,从TOML文件或字符串创建一个Box对象(所有Box参数都可以传递)
from_csv** Classmethod,从一个CSV文件或字符串创建一个BoxList对象(可以传递所有BoxList参数)
    • 不适用于 BoxList,仅适用于 Box ** 不适用于 Box,仅适用于 BoxList。

文章来源: blog.csdn.net,作者:Serendipity·y,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/Forever_wj/article/details/120872940

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。