YAML 是一种较为人性化的数据序列化语言,可以配合目前大多数编程语言使用。
YAML 的语法比较简洁直观,特点是使用空格来表达层次结构,其最大优势在于数据结构方面的表达,所以 YAML 更多应用于编写配置文件,其文件一般以 .yaml 为后缀。
它的基本语法规则如下:
YAML 支持的数据结构有三种。
在一个文件中可以使用
---
表示文件开头...
表示文件结尾,这样一个文件里等于同时保存多个文件了。
key: value
形式表示注意,冒号之后要加空格,否则无法解析
father: dad
Father: Dad
{ father: 'dad', Father: 'Dad' }
这里由于大小写敏感,是两个对象
father:
child1: Jack
child2: Bob
{ father: { child1: 'Jack', child2: 'Bob' } }
father: {child1: Jack, child2: Bob}
{ father: { child1: 'Jack', child2: 'Bob' } }
animals:
- Cat
- Dog
- Goldfish
{ animals: [ 'Cat', 'Dog', 'Goldfish' ] }
values: [value1, value2, value3]
{ values: [ 'value1', 'value2', 'value3' ] }
values:
-
- value1
- value2
-
- value3
- value4
{ values: [ [ 'value1', 'value2' ], [ 'value3', 'value4' ] ] }
注意,第2行和第5行不能添加东西,否则解析出来就不是二维数组了,如下面反例
values:
- sx1
- value1
- value2
- sx2
- value3
- value4
{ values: [ 'sx1 - value1 - value2', 'sx2 - value3 - value4' ] }
纯量是最基本的,不可再分的值,包括:
下面是纯量的使用示例
boolean:
- TRUE #true,True都可以
- FALSE #false,False都可以
float:
- 3.14
- 6.8523015e+5 #可以使用科学计数法
int:
- 123
- 0b1010_0111_0100_1010_1110 #二进制表示
null:
nodeName: 'node'
parent: ~ #使用~表示null
string:
- 哈哈
- 'Hello world' #可以使用双引号或者单引号包裹特殊字符
- newline
newline2 #字符串可以拆成多行,每一行会被转化成一个空格
date:
- 2018-02-17 #日期必须使用ISO 8601格式,即yyyy-MM-dd
datetime:
- 2018-02-17T15:02:31+08:00 #时间使用ISO 8601格式,时间和日期之间使用T连接,最后使用+代表时区
JSON显示如下:
{ boolean: [ true, false ],
float: [ 3.14, 685230.15 ],
int: [ 123, 685230 ],
null: { nodeName: 'node', parent: null },
string: [ '哈哈', 'Hello world', 'newline newline2' ],
date: [ Sat Feb 17 2018 08:00:00 GMT+0800 (中国标准时间) ],
datetime: [ Sat Feb 17 2018 15:02:31 GMT+0800 (中国标准时间) ] }
字符串是最常见,也是最复杂的一种数据类型。
字符串一般不需要用引号包裹,但是如果字符串中使用了反斜杠“\”开头的转义字符就必须使用引号包裹
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!"' # 单双引号支持嵌套"
- \n \r
- '\n \r'
- "\n \r"
其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!"',
'\\n \\r',
'\\n \\r',
'\n \r' ] }
自己注意一下不同引号对结果的影响
对于多行的文字,YAML 提供了两种特殊的语法支持
保留换行(Newlines preserved)
使用**竖线符“ | ”**来表示该语法,每行的缩进和行尾空白都会被去掉,而额外的缩进会被保留
lines: |
我是第一行
我是第二行
我是吴彦祖
我是第四行
我是第五行
JSON格式如下:
{ lines: '我是第一行\n我是第二行\n 我是吴彦祖\n 我是第四行\n我是第五行\n' }
折叠换行(Newlines folded)
使用**右尖括号“ > ”**来表示该语法,只有空白行才会被识别为换行,原来的换行符都会被转换成空格
lines: >
我是第一行
我也是第一行
我仍是第一行
我依旧是第一行
我是第二行
这么巧我也是第二行
其JSON格式如下:
{ lines: '我是第一行 我也是第一行 我仍是第一行 我依旧是第一行\n我是第二行 这么巧我也是第二行\n' }
注意,此方法最后一行末尾换行符会被识别
还可以用+
和-
来选择是否保留蚊子块末尾的换行符
s1: |
Foo
s2: |+
Foo
s3: |-
Foo
其JSON如下:
{ s1: 'Foo\n', s2: 'Foo\n', s3: 'Foo' }
boolean:
- True
- true
- False
- FALSE
其JSON如下:
{ boolean: [ true, true, false, false ] }
支持二进制表示
int:
- 666 # 十进制
- 0b10 # 0b 前缀,二进制
- 010 # 0 前缀,八进制
- 0x10 # 0x 前缀,十六进制
其JSON如下:
{ int: [ 666, 2, 8, 16 ] }
支持科学计数法
float:
- 3.14
- 6.8523015e+5
- 6E3
其JSON如下:
{ float: [ 3.14, 685230.15, 6000 ] }
指数必须是整数
nulls:
-
- null
- Null
- NULL
- ~
其JSON如下:
{ nulls: [ null, null, null, null, null ] }
date1: 2020-05-20 13:14:00.820+08:00 # +8表示该时间就是东八区的时间
date2: 2020-05-20 13:14:00.820 # 不加时区默认本初子母线的时间
date3: 2020-05-20 13:14:00.820+8
其JSON显示为:
{ date1: Wed May 20 2020 13:14:00 GMT+0800 (中国标准时间),
date2: Wed May 20 2020 21:14:00 GMT+0800 (中国标准时间),
date3: Wed May 20 2020 13:14:00 GMT+0800 (中国标准时间) }
!!
(双感叹号+目标类型)来强制转换类型,下面是内置类型
!!int
:整数类型!!float
:浮点类型!!bool
:布尔类型!!str
:字符串类型!!binary
:也是字符串类型!!timestamp
:日期时间类型!!null
:空值!!set
:集合!!omap
,!!pairs
:键值列表或对象列表!!seq
:序列,也是列表!!map
:键值表# 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 提供了由锚点标签“&”和引用标签“*”组成的语法,利用这套语法可以快速引用相同的一些数据…
# 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 } }
锚点必须加在冒号后,值之前,然后用*符号可以解引用
配合合并标签“<<”使用可以与任意数据进行合并,你可以把这套操作想象成面向对象语言中的继承
# 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' } }
例如yaml文件如下:
---
human: &human
sex: 男
student: &st
no: !!int 100000
name: ice
<<: *human
grade: 研一
score: !!float 3.14
fruits:
- apple
- banana
- orange
child: *st
matrix:
-
- 1
- 2
- 3
-
- 4
- 5
- 6
-
- 7
- 8
- 9
...
对应解析的Python代码如下:
from ruamel import yaml
with open("config.yaml", encoding="utf8") as f:
config = yaml.load(f, Loader=yaml.RoundTripLoader)
print(config["student"]["name"]) # ice
print(config["student"]["score"]) # 3.14
print(config["student"]["sex"]) # 男
print(config["fruits"][1]) # banana
print(config["child"]["sex"]) # 男
print(config["matrix"]) # [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- stra.cn 版权所有 赣ICP备2024042791号-4
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务