1. yaml文件介绍

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

  • 安装yaml
pip3 install pyyaml

导入的模块为yaml(import yaml)

  • yaml文件的规则
  • 大小写敏感
  • 使用缩进表示层级关系;
  • 使用空格键缩进,而非Tab键缩进
  • 缩进的空格数目不重要,只需要相同层级的元素左侧对齐
  • 文件中的字符串不需要使用引号标注,但若字符串包含有特殊字符则需用引号标注
  • 注释标识为#
  • yaml文件数据结构
  • 对象:键值对的集合(简称 “映射或字典”)
    键值对用冒号 “:” 结构表示,冒号与值之间需用空格分隔
  • 数组:一组按序排列的值(简称 “序列或列表”)
    数组前加有 “-” 符号,符号与值之间需用空格分隔
  • 纯量(scalars):单个的、不可再分的值(如:字符串、bool值、整数、浮点数、时间、日期、null等)
    None值可用null,也可 ~ 表示

典型的yaml数据格式以及对应的python输出类型如下:

# 1. 对象:yaml键值对:即python中字典
usr: my
psw: 123455
s: " abc\n"
#解析后:{'usr': 'my', 'psw': 123455, 's': ' abc\n'}

# 2. 数组:yaml键值对中嵌套数组
usr3:
 - a
 - b
 - c
usr4:
 - b
#解析后:{'usr3': ['a', 'b', 'c'], 'usr4': ['b']}

# 3. 纯量
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)}

# 4. 引用
name: &name 灰蓝
tester: *name
# 相当于
name: 灰蓝
tester: 灰蓝
#解析后内容:{'name': '灰蓝', 'tester': '灰蓝'}

# 5. 强制转换
str: !!str 3.14
int: !!int "123"
# 输出:{'int': 123, 'str': '3.14'}

2. 读取yaml

2.1 读取嵌套键值对

yaml文件内容为:

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

程序代码如下:

import yaml
import os
current_path = os.path.abspath(".")
yaml_path = os.path.join(current_path, "test.yaml")
file = open(yaml_path, 'r', encoding="utf-8")
file_data = file.read() #读取file内容
file.close()

print(type(file_data))
print(file_data)

#*****************转化为字典***************
data = yaml.load(file_data) #转换为字典类型
print(type(data))
print(data)

输出如下,可以看出注释内容也打印出来了。

<class 'str'>
# yaml键值对嵌套:即python中字典嵌套字典
usr1:
  name: a
  psw: 123
usr2:
  name: b
  psw: 456
<class 'dict'>
{'usr1': {'name': 'a', 'psw': 123}, 'usr2': {'name': 'b', 'psw': 456}}

2.2 读取数组类型

yaml文件内容为:

# yaml键值对中嵌套数组
usr3:
  - a
  - b
  - c
usr4:
  - b

同样使用上述代码,输出为:

<class 'str'>
# yaml键值对中嵌套数组
usr3:
  - a
  - b
  - c
usr4:
  - b
<class 'dict'>
{'usr3': ['a', 'b', 'c'], 'usr4': ['b']}

3. python对象生成yaml文档

3.1 dump方法

通过yaml.dump()方法不会将列表或字典数据进行转化yaml标准模式,只会将数据生成到yaml文档中

# 将python对象生成yaml文档
import os
import yaml

def generate_yaml_doc(yaml_file):
  py_object = {'school': 'zhang',
         'students': ['a', 'b']}
  file = open(yaml_file, 'w', encoding='utf-8')
  yaml.dump(py_object, file)
  file.close()

current_path = os.path.abspath(".")
yaml_path = os.path.join(current_path, "generate.yaml")
generate_yaml_doc(yaml_path)

输出generate.yaml中的内容如下,显然students不是yaml的标准格式,它只是简单的保存了原数据格式。

school: zhang
students: [a, b]

3.2 ruamel模块的方法

ruamel会将数据转换为标准的yaml内容。

  • 准备
  • 安装:pip3 install ruamel.yaml
  • 导入模块:from ruamel import yaml

示例程序:

import os

def generate_yaml_doc_ruamel(yaml_file):
  from ruamel import yaml
  py_object = {'school': 'zhang',
         'students': ['a', 'b']}
  file = open(yaml_file, 'w', encoding='utf-8')
  yaml.dump(py_object, file, Dumper=yaml.RoundTripDumper)
  file.close()

current_path = os.path.abspath(".")
yaml_path = os.path.join(current_path, "generate.yaml")
generate_yaml_doc_ruamel(yaml_path)

输出的generate.yaml中的内容如下,students转化为标准的yaml格式。

school: zhang
students:
- a
- b