一、基本介绍
YAML是一种计算机数据序列化语言。(YAML is a computer data serialization language.)YAML is a human friendly data serialization standard for all programming languages(YAML是一个对所有编程语言都很友好的数据序列化标准),可以用于多种编程语言。因其良好的跨语言、跨平台、易于理解、格式简单而广泛应用于配置文件、数据文件、日志文件等。
二、数据类型
YAML文档以人类可读的文本形式表示计算机程序的本地数据结构。YAML文档中的节点可以有三种基本数据类型:
2.1 纯量(scalars)/标量
单个的、不可再分的值(如:字符串、bool值、整数、浮点数、时间、日期、null等。
2.1.1 字符串
字符串一般不需要用引号包裹,但是如果字符串中使用了反斜杠“\”开头的转义字符就必须使用引号包裹
# YAML
strings:
- Hello without quote # 不用引号包裹
- Hello
world # 拆成多行后会自动在中间添加空格
- 'Hello with single quotes' # 单引号包裹
- "Hello with double quotes" # 双引号包裹
- "I am fine. \u263A" # 使用双引号包裹时支持 Unicode 编码
- "\x0d\x0a is \r\n" # 使用双引号包裹时还支持 Hex 编码
- 'He said: "Hello!"' # 单双引号支持嵌套"
// JSON
"strings":
[ "Hello without quote",
"Hello world",
"Hello with single quotes",
"Hello with double quotes",
"I am fine. ☺",
"\r\n is \r\n",
"He said: 'Hello!'" ]
2.1.2 保留换行(Newlines preserved)
使用**竖线符“ | ”**来表示该语法,每行的缩进和行尾空白都会被去掉,而额外的缩进会被保留
# YAML
lines: |
我是第一行
我是第二行
我是吴彦祖
我是第四行
我是第五行
// JSON
"lines": "我是第一行\n我是第二行\n 我是吴彦祖\n 我是第四行\n我是第五行"
2.1.3 布尔值(Boolean)
“true”、“True”、“TRUE”、“yes”、“Yes”和“YES”皆为真
“false”、“False”、“FALSE”、“no”、“No”和“NO”皆为假
# YAML
boolean:
- true # True、TRUE
- yes # Yes、YES
- false # False、FALSE
- no # No、NO
// JSON
"boolean": [ true, true, false, false ]
2.1.4 整数(Integer)
支持二进制表示
# YAML
int:
- 666
- 0001_0000 # 二进制表示
// JSON
"int": [ 666, 4096 ]
2.1.5 浮点数(Floating Point)
支持科学计数法
# YAML
float:
- 3.14
- 6.8523015e+5 # 使用科学计数法
// JSON
"float": [ 3.14, 685230.15 ]
2.1.6 空(Null)
“null”、“Null”和“~”都是空,不指定值默认也是空
# YAML
nulls:
- null
- Null
- ~
-
// JSON
"nulls": [ null, null, null, null ]
2.1.7 时间戳(Timestamp)
# YAML
date1: 2020-05-26
date2: 2020-05-26T01:00:00+08:00
dete3: 2020-05-26T02:00:00.10+08:00
date4: 2020-05-26 03:00:00.10 +8
// JavaScript
date1: Tue May 26 2020 08:00:00 GMT+0800 (中国标准时间),
date2: Tue May 26 2020 01:00:00 GMT+0800 (中国标准时间),
dete3: Tue May 26 2020 02:00:00 GMT+0800 (中国标准时间),
date4: Tue May 26 2020 03:00:00 GMT+0800 (中国标准时间)
2.1.8 类型转换
YAML 支持使用严格类型标签“!!”(双感叹号+目标类型)来强制转换类型
# YAML
a: !!float '666' # !! 为严格类型标签
b: '666' # 其实双引号也算是类型转换符
c: !!str 666 # 整数转为字符串
d: !!str 666.66 # 浮点数转为字符串
e: !!str true # 布尔值转为字符串
f: !!str yes # 布尔值转为字符串
// JSON
"a": 666,
"b": "666",
"c": "666",
"d": "666.66",
"e": "true"
"f": "yes"
YAML 也可以使用一些更高级的类型,但是并不一定兼容所有解析器,包括集合(Sets)、有序映射(Ordered Map)、十六进制数据(Hexdecimal)和二进制数据(Binary)。
2.2 数组
一组按序排列的值(简称 “序列或列表”)数组前加有 “-” 符号,符号与值之间需用空格分隔。
2.2.1 一组以**区块格式(Block Format)(即“破折号+空格”)**开头的数据组成一个数组
# YAML
values:
- value1
- value2
- value3
// JSON
"values": [ "value1", "value2", "value3" ]
2.2.2 同时也支持**内联格式(Inline Format)**来表达(用方括号包裹,逗号加空格分隔,类似 JSON)
# YAML
values: [value1, value2, value3]
// JSON
"values": [ "value1", "value2", "value3" ]
2.2.3支持多维数组(用缩进表示层级关系)
# YAML
values:
-
- value1
- value2
-
- value3
- value4
// JSON
"values": [ [ "value1", "value2"], ["value3", "value4"] ]
2.3对象(Mapping)
键值对的集合(简称 “映射或字典”)键值对用冒号 “:” 结构表示,冒号与值之间需用空格分隔。
2.3.1 表示以键值对(key: value)形式出现的数据
使用“冒号+空格”来分开键与值
# YAML
key: value
// JSON
"key": "value"
2.3.2 支持多层嵌套
# YAML
key:
child-key1: value1
child-key2: value2
// JSON
"key": {
"child-key1": "value1",
"child-key2": "value2",
}
2.3.3支持流式风格( Flow style)的语法
(用花括号包裹,用逗号加空格分隔,类似 JSON)
# YAML
key: { child-key1: value1, child-key2: value2 }
// JSON
"key": { "child-key1": "value1", "child-key2": "value2" }
2.3.4 使用问号
使用问号“?”*声明一个复杂对象,允许你使用多个词汇(数组)来组成键
# YAML
?
- keypart1
- keypart2
:
- value1
- value2
2.4 锚点
为了保持内容的简洁,避免过多重复的定义,YAML 提供了由**锚点标签“&”和引用标签“*”**组成的语法,利用这套语法可以快速引用相同的一些数据…
# YAML
a: &anchor # 设置锚点
one: 1
two: 2
three: 3
b: *anchor # 引用锚点
// JSON
"a": {
"one": 1,
"two": 2,
"three": 3
},
"b": {
"one": 1,
"two": 2,
"three": 3
}
2.5 合并标签
配合**合并标签“<<”**使用可以与任意数据进行合并,你可以把这套操作想象成面向对象语言中的继承…
# YAML
human: &base # 添加名为 base 的锚点
body: 1
hair: 999
singer:
<<: *base # 引用 base 锚点,实例化时会自动展开
skill: sing # 添加额外的属性
programer:
<<: *base # 引用 base 锚点,实例化时会自动展开
hair: 6 # 覆写 base 中的属性
skill: code # 添加额外的属性
// JSON
"human": { "body": 1, "hair": 999 },
"singer": { "body": 1, "hair": 999, "skill": "sing" },
"programer": { "body": 1, "hair": 6, "skill": "code" }
其他数据类型查看https://yaml.com/doc/glossary/
三、yaml 文件的特点
3.1 大小写敏感
One: 1
one: 2
3.2 使用缩进表示层级关系
3.3 缩进时不允许使用Tab键,只允许使用空格
3.4 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可;
# YAML
one:
two: 2
three:
four: 4
five: 5
// 以上的内容转成 JSON 后
"one": {
"two": 2,
"three": {
"four": 4,
"five": 5
}
}
3.5 文件中的字符串不需要使用引号标注,但若字符串包含有特殊字符则需用引号标注;
3.6 注释标识为#
# 我是注释
# 我也是注释
注:只支持单行注释
3.7一个文件中可以包含多个文件的内容
- 用“ — ”即三个破折号表示一份内容的开始
- 用“ … ”即三个小数点表示一份内容的结束(非必需)
---
# 这是第一份内容
one: 1
# 其他内容...
...
---
# 这是第二份内容
two: 2
# 其他内容...
四、使用方法
官网给出编程语言对应的第三方库,下面以python为例,展示YAML的实际使用.
4.1 安装方法
pip install pyyaml
4.2 解析yaml 文件
import yaml
with open('config.yaml', 'r') as f:
config = yaml.safe_load(f)
print(config)
4.3 生成yaml文件
import yaml
data = {'name': '张三', 'age': 18, 'gender': '男'}
with open('data.yaml', 'w') as f:
yaml.dump(data, f)
4.4 一个yaml文件中包含多个文档
file = open('./test1.yaml', 'r', encoding="utf-8")
file_data = file.read()
file.close()
all_data = yaml.load_all(file_data)
for data in all_data:
print(data)
4.5 使用ruamel模块中的yaml方法处理yaml文档
4.5.1 使用ruamel写入yaml文件
py_object = {'school': 'zhang',
'students': ['a', 'b']}
file = open('./Generation1.yaml', 'w', encoding='utf-8')
yaml.dump(py_object, file, Dumper=yaml.RoundTripDumper)
4.5.2 使用ruamel读取yaml文件
file = open('./test.yaml', 'r', encoding='utf-8')
data = yaml.load(file.read(),Loader=ruamel.yaml.Loader)
file.close()
print(data)
参考&&引用
完整代码查看 我的github