python 之yaml模块使用总结

一、yaml文件介绍

YAML是一种简洁的非标记语言。其以数据为中心,使用空白,缩进,分行组织数据,从而使得表示更加简洁。

1.1 yaml文件规则

基本规则:
    大小写敏感
    使用缩进表示层级关系
    缩进时不允许使用Tab键,只允许使用空格。
    缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
    使用#表示注释
    字符串可以不用引号标注

1.2 yaml文件数据结构

    对象:键值对的集合(简称 "映射或字典")
    键值对用冒号 “:” 结构表示,冒号与值之间需用空格分隔
    数组:一组按序排列的值(简称 "序列或列表")
    数组前加有 “-” 符号,符号与值之间需用空格分隔
    纯量(scalars):单个的、不可再分的值(如:字符串、bool值、整数、浮点数、时间、日期、null等)
    None值可用null可 ~ 表示

二、安装yaml

pip命令: pip install PyYaml

PyYaml引入:import yaml

三、python中读取yaml配置文件

3.1 读取yaml文件数据

python通过open方式读取文件数据,再通过load函数将数据转化为列表或字典;

1 import yaml
2 
3 def get_yaml():
4     file_yaml = 'test.yaml'
5     rf = open(file=file_yaml, mode='r', encoding='utf-8')
6     crf = rf.read()
7     rf.close()  # 关闭文件
8     yaml_data = yaml.load(stream=crf, Loader=yaml.FullLoader)
9     return yaml_data

3.1.1 yaml文件数据为键值对

(1)yaml文件中内容为键值对:

# yaml键值对:即python中字典
usr: my
psw: 123455
s: " abc\n"

python解析yaml文件后获取的数据:

{'usr': 'my', 'psw': 123455, 's': ' abc\n'}

(2)yaml文件中内容为“键值对'嵌套"键值对"

# yaml键值对嵌套:即python中字典嵌套字典
usr1:
  name: a
  psw: 123
usr2:
  name: b
  psw: 456

python解析yaml文件后获取的数据:

{'usr1': {'name': 'a', 'psw': 123}, 'usr2': {'name': 'b', 'psw': 456}}

(3)yaml文件中“键值对”中嵌套“数组”

# yaml键值对中嵌套数组
usr3:
  - a
  - b
  - c
usr4:
  - b
python解析yaml文件后获取的数据:

{'usr3': ['a', 'b', 'c'], 'usr4': ['b']}

 3.1.2 yaml文件数据为数组

(1)yaml文件中内容为数组
# yaml数组
- a
- b
- 5
python解析yaml文件后获取的数据:
['a', 'b', 5]

(2)yaml文件“数组”中嵌套“键值对”
# yaml"数组"中嵌套"键值对"
- usr1: aaa
- psw1: 111
  usr2: bbb
  psw2: 222
python解析yaml文件后获取的数据:
[{'usr1': 'aaa'}, {'psw1': 111, 'usr2': 'bbb', 'psw2': 222}]

3.1.3 yaml文件中基本数据类型:

# 纯量
s_val: name              # 字符串:{'s_val': 'name'}
spec_s_val: "name\n"    # 特殊字符串:{'spec_s_val': 'name\n'}
num_val: 31.14          # 数字:{'num_val': 31.14}
bol_val: true           # 布尔值:{'bol_val': True}
nul_val: null           # null值:{'nul_val': None}
nul_val1: ~             # null值:{'nul_val1': None}
time_val: 2018-03-01t11:33:22.55-06:00     # 时间值:{'time_val': datetime.datetime(2018, 3, 1, 17, 33, 22, 550000)}
date_val: 2019-01-10    # 日期值:{'date_val': datetime.date(2019, 1, 10)}

 3.2. yaml文件内中引用

yaml文件中内容:
animal3: &animal3 fish    # "&"符号标记锚点
test: *animal3     # 直接使用*号引用
python读取的数据:
{'animal3': 'fish', 'test': 'fish'}

3.3 yaml文件里引用yaml文件

背景: 项目中有多个测试用例,测试用例使用yaml的配置文件,各个测试用例的yaml配置文件中有一些共有的属性,

把这些共有的属性抽取出来放在一个yaml文件中,问题来了:如何在测试用例的Yaml文件引用这些共享的Yaml文件

doc01.yaml:

demo01:
- Ruby

document.yaml:

languages:
- Ruby
- Perl
- Python
test: !include doc01.yaml

yaml文件目录结构如下:

 python实现:

 1 import yaml
 2 import os.path
 3 
 4 
 5 def include(self,node):
 6     # filename = os.path.join(self._root, self.construct_scalar(node))
 7     filename = os.path.join(os.getcwd(), 'data', 'doc01.yaml')
 8     with open(filename, 'r') as fr:
 9         return yaml.load(fr, Loader=yaml.FullLoader)
10 yaml.add_constructor('!include', include)
11 
12 def load_yaml(file_name):
13     """Load YAML file to be dict"""
14     if os.path.exists(file_name):
15         with open(file_name, 'r', encoding="utf-8") as fr:
16             dict_obj = yaml.load(fr, Loader=yaml.FullLoader)
17         return dict_obj
18     else:
19         raise FileNotFoundError('NOT Found YAML file %s' % file_name)
20 
21 
22 if __name__ == '__main__':
23     yaml_dict = load_yaml("document.yaml")
24     print(yaml_dict)

运行结果:

四、python中读取多个yaml文档

1. 多个文档在一个yaml文件,使用 --- 分隔方式来分段
如:yaml文件中数据
# 分段yaml文件中多个文档
---
animal1: dog
age: 2
---
animal2: cat
age: 3

2. python脚本读取一个yaml文件中多个文档方法
python获取yaml数据时需使用load_all函数来解析全部的文档,再从中读取对象中的数据
# yaml文件中含有多个文档时,分别获取文档中数据

 1 def get_yaml_load_all(yaml_file):
 2     # 打开yaml文件
 3     file = open(yaml_file, 'r', encoding="utf-8")
 4     file_data = file.read()
 5     file.close()
 6     all_data = yaml.full_load_all(file_data)
 7     for data in all_data:
 8         print(data)
 9 current_path = os.path.abspath(".")
10 yaml_path = os.path.join(current_path, "config.yaml")
11 get_yaml_load_all(yaml_path)

"""结果
{'animal1': 'dog', 'age': 2}
{'animal2': 'cat', 'age': 3}
"""

五、python对象生成yaml文档

1. 直接导入yaml(即import yaml)生成的yaml文档

使用yaml.dump()方法,加入allow_unicode=True参数防止写入的中文乱码,会将列表或字典数据进行转化yaml标准模式,并生成到yaml文档中

# 将python对象生成yaml文档

 1 import yaml
 2 import os
 3 
 4 
 5 def generate_yaml_doc(yaml_file):
 6     py_object = {'school': 'zhang',
 7                  'students': ['a', 'b']}
 8     file = open(yaml_file, 'w', encoding='utf-8')
 9     yaml.dump(py_object, file)
10     file.close()
11 
12 
13 current_path = os.path.abspath(".")  # 当前文件目录绝对路径
14 yaml_path = os.path.join(current_path, "generate.yaml")
15 generate_yaml_doc(yaml_path)

""生成yaml文件内容:

school: zhang
students:
- a
- b

"""
部分内容摘自:https://www.cnblogs.com/lisa2016/p/11764808.html


posted @ 2022-05-06 10:19  别摸我的马甲线  阅读(8306)  评论(0编辑  收藏  举报