Python 读写 yaml 文件
一、yaml文件规则
- 区分大小写;
- 使用缩进表示层级关系;
- 使用空格键缩进,而非Tab键缩进
- 缩进的空格数目不固定,只需要相同层级的元素左侧对齐;
- 文件中的字符串不需要使用引号标注,但若字符串包含有特殊字符则需用引号标注;
- 注释标识为#
二、yaml数据结构
- YAML 支持的数据结构有三种。
- 对象
键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
对象的一组键值对,使用冒号结构表示。
- 数组
一组按次序排列的值,又称为序列(sequence) / 列表(list)
一组连词线开头的行,构成一个数组。
- 纯量(scalars)
单个的、不可再分的值
包括字符串,布尔值,整数,浮点数,Null,时间,日期
三、一个yaml文件
name: LeBron James age: 37 spouse: name: LeBron James age: 37 children: - LeBron James Jr age: 18 - Bryce Maximus James age: 15
和它对应的json文件如下:
{ name: 'LeBron James', age: 37, spouse: { name: 'LeBron James', age: 37 }, children: [ { name: 'LeBron James Jr', age: 18 }, { name: 'Bryce Maximus James', age: 15 } ] }
四、通常 Python 使用的 Yaml 文件处理的包有 2 个。
可以理解为 PyYAML 是 Python 自带的 Yaml 数据处理库,ruamel.yaml 是 PyYAML 的增强版。因此使用 ruamel.yaml 的会比较多,而且很多语法和函数都是通用的。
安装
PyYAML 和 ruamel.yaml 都需要安装。使用 pip install 进行安装就可以了。过程非常简单。
pip install pyyaml
pip install ruamel.yaml
五、用原生的pyyaml模块写入字典嵌套字典的复杂数据
import yaml desired_caps = { 'platformName': 'Android', # 被测手机是安卓 'platformVersion': 'platformVersion', # 手机安卓版本 'deviceName': 'deviceName', # 设备名,安卓手机可以随意填写 'appPackage': 'com.mobivans.onestrokecharge', # 启动APP Package名称 'appActivity': 'com.mobivans.onestrokecharge.activitys.MainActivity', # 启动Activity名称 'unicodeKeyboard': True, # 使用自带输入法,输入中文时填True 'resetKeyboard': True, # 执行完程序恢复原来输入法 'noReset': True, # 不要重置App 'newCommandTimeout': 60000, 'udid': {"devicesname":"127.0.0.1:62001"} } # 将以上字典写入到yaml文件 with open('desired_caps.yaml', 'w', encoding='utf-8') as f: # 将字典写入到yaml文件中 yaml.dump(desired_caps, f)
六、ruamel.yaml写入
使用方法跟yaml差不多,只是在使用dump方法多个一个参数:Dumper=yaml.RoundTripDumper
from ruamel import yaml desired_caps = { 'platformName': 'Android', # 被测手机是安卓 'platformVersion': 'platformVersion', # 手机安卓版本 'deviceName': 'deviceName', # 设备名,安卓手机可以随意填写 'appPackage': 'com.mobivans.onestrokecharge', # 启动APP Package名称 'appActivity': 'com.mobivans.onestrokecharge.activitys.MainActivity', # 启动Activity名称 'unicodeKeyboard': True, # 使用自带输入法,输入中文时填True 'resetKeyboard': True, # 执行完程序恢复原来输入法 'noReset': True, # 不要重置App 'newCommandTimeout': 60000, 'udid': {"devicesname":"127.0.0.1:62001"} } # 将以上字典写入到yaml文件 with open('desired_caps.yaml', 'w', encoding='utf-8') as f: # 将字典写入到yaml文件中 yaml.dump(desired_caps, f, Dumper=yaml.RoundTripDumper)
注意:如果不加Dumper=yaml.RoundTripDumper,写入的时候有字典的嵌套,例如上述字典中udid字段,出现了大括号:{androidProcess: 'com.tencent.mm:tools'},这不是真正的yaml数,如下图
那么加上Dumper=yaml.RoundTripDumper写入的内容形式如下
七、ruamel.yaml读取yaml文件内容
使用ruamel.yaml模块也能读yaml文件,使用方法相对于之前的yaml.load方法多加一个参数:Loader=yaml.Loader
from ruamel import yaml with open('desired_caps.yaml', 'r', encoding="utf-8") as f: # yaml文件中读取内容 msg = yaml.load(f.read(), Loader=yaml.Loader) print(msg) # 查看数据类型--》字典 print('读取出来数据类型为:', type(msg))
八、写入中文到yaml文件中
from ruamel import yaml # 将字典添加到yaml文件中 data = {'name': '金毛狮王'} # 将以上字典写入到yaml文件 with open('desired_caps.yaml', 'w', encoding='utf-8') as f: # 将字典写入到yaml文件中 yaml.dump(data, f, Dumper=yaml.RoundTripDumper)
运行后,查看yaml文件发现中文字符被转码成下面这种情况了
那么怎么解决上述问题呢?只需要在后面添加allow_unicode=True即可
from ruamel import yaml # 将字典添加到yaml文件中 data = {'name': '金毛狮王'} # 将以上字典写入到yaml文件 with open('desired_caps.yaml', 'w', encoding='utf-8') as f: # 将字典写入到yaml文件中 yaml.dump(data, f, Dumper=yaml.RoundTripDumper, allow_unicode=True)
再次查看如下:
注意:以上内容,如果是追加写入,则需要改变文件方式为,例如使用a+模式