学好 Yaml
Posted 看,未来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学好 Yaml相关的知识,希望对你有一定的参考价值。
文章目录
简介
之前是快速上手 yaml,这可以让我学习 kubernetes,但是真要工作用,总是差了一点东西,所以今天回炉重造。
YAML 是一种较为人性化的数据序列化语言,可以配合目前大多数编程语言使用。
YAML 的语法比较简洁直观,特点是使用空格来表达层次结构,其最大优势在于数据结构方面的表达,所以 YAML 更多应用于编写配置文件,其文件一般以 .yaml(或者 .yml) 为后缀。
它的基本语法规则如下:
- 大小写敏感
- 使用缩进表示层级关系
- 缩进时不允许使用Tab键,只允许使用空格
- 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
- #表示注释,从这个字符一直到行尾,都会被解析器忽略。
YAML 支持的数据结构有三种。
对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
纯量(scalars):单个的、不可再分的值
在一个文件中可以使用—表示文件开头…表示文件结尾,这样一个文件里等于同时保存多个文件了。
学习工具
学而不思则罔。
pip install PyYaml
import yaml
f = open("yaml.yaml")
res = yaml.safe_load(f)
print(res)
对象
使用key: value
形式表示
注意,冒号之后要加空格,否则无法解析
father: dad
Father: Dad
‘father’: ‘dad’, ‘Father’: ‘Dad’
这里由于大小写敏感,是两个对象
支持多层嵌套(用缩进表示层级关系)
father:
child1: Jack
child2: Bob
‘father’: ‘child1’: ‘Jack’, ‘child2’: ‘Bob’
支持**流式风格( Flow style)**的语法(用花括号包裹,用逗号加空格分隔,类似 JSON)
father: child1: Jack, child2: Bob
‘father’: ‘child1’: ‘Jack’, ‘child2’: ‘Bob’
数组
一组以区块格式(Block Format)(即“破折号+空格”)开头的数据组成一个数组
animals:
- Cat
- Dog
- Goldfish
‘animals’: [‘Cat’, ‘Dog’, ‘Goldfish’]
这里要和这种格式对比一下:
animals:
- Cat
- Dog
- Goldfish
‘animals’: [‘Cat’, ‘Dog’, ‘Goldfish’]
这俩是一个意思哈,第一次遇到的时候给我整懵了,我是认也不是,不认也不是。
同时也支持内联格式(Inline Format)来表达(用方括号包裹,逗号加空格分隔,类似 JSON)
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’ ]
讲真,我不知道这东西在哪里用。
好,我们继续做个辨析:
values:
-
- value1
- value2
-
- value3
- value4
如果是这样,‘values’: [None, ‘value1’, ‘value2’, None, ‘value3’, ‘value4’]
values:
-
- value1
- value2
-
- value3
- value4
跟上一个没差
values:
-
- value1
- value2
-
- value3
- value4
这个就是正常的二维数组了:‘values’: [[‘value1’, ‘value2’], [‘value3’, ‘value4’]]
没啥特别的意思,如果是咱写代码,就写最开始那种标准的,别整这些花里胡哨的后来人看的都麻烦。
纯量
纯量是最基本的,不可再分的值,包括:
字符串
布尔值
整数
浮点数
Null
时间
日期
下面是纯量的使用示例
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], None: 'nodeName': 'node', 'parent': None,
'string': ['哈哈', 'Hello world', 'newline newline2'], 'date': [datetime.date(2018, 2, 17)],
'datetime': [datetime.datetime(2018, 2, 17, 15, 2, 31, tzinfo=datetime.timezone(datetime.timedelta(seconds=28800)))]
字符串
字符串是最常见,也是最复杂的一种数据类型。
字符串一般不需要用引号包裹,但是如果字符串中使用了反斜杠“\\”开头的转义字符就必须使用引号包裹
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我是第五行’
折叠换行(Newlines folded)
使用**右尖括号“ > ”**来表示该语法,只有空白行才会被识别为换行,原来的换行符都会被转换成空格
lines: >
我是第一行
我也是第一行
我仍是第一行
我依旧是第一行
我是第二行
这么巧我也是第二行
其JSON格式如下:
‘lines’: ‘我是第一行 我也是第一行 我仍是第一行 我依旧是第一行\\n我是第二行 这么巧我也是第二行’
注意,此方法最后一行末尾换行符会被识别
还可以用+和-来选择是否保留文字块末尾的换行符
s1: |
Foo
s2: |+
Foo
s3: |-
Foo
其JSON如下:
‘s1’: ‘Foo\\n’, ‘s2’: ‘Foo\\n’, ‘s3’: ‘Foo’
布尔值
“true”、“True”、“TRUE”、“yes”、“Yes”和“YES”皆为真
“false”、“False”、“FALSE”、“no”、“No”和“NO”皆为假
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, ‘6E3’]
指数必须是整数
空值
nulls:
-
- null
- Null
- NULL
- ~
其JSON如下:
‘nulls’: [None, None, None, None, None]
时间戳
YAML 也支持 ISO 8601 格式的时间数据
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’: datetime.datetime(2020, 5, 20, 13, 14, 0, 820000, tzinfo=datetime.timezone(datetime.timedelta(seconds=28800))),
‘date2’: datetime.datetime(2020, 5, 20, 13, 14, 0, 820000),
‘date3’: datetime.datetime(2020, 5, 20, 13, 14, 0, 820000, tzinfo=datetime.timezone(datetime.timedelta(seconds=28800)))
类型转换
YAML 支持使用严格类型标签!!(双感叹号+目标类型)来强制转换类型,下面是内置类型
!!int :整数类型
!!float :浮点类型
!!bool:布尔类型
!!str:字符串类型
!!binary:也是字符串类型
!!timestamp :日期时间类型
!!null:空值
!!set:集合
!!omap,!!pairs :键值列表或对象列表
!!seq:序列,也是列表
!!map:键值表
a: !!float '666' # !! 为严格类型标签
b: '666' # 其实双引号也算是类型转换符
c: !!str 666 # 整数转为字符串
d: !!str 666.66 # 浮点数转为字符串
e: !!str true # 布尔值转为字符串
f: !!str yes # 布尔值转为字符串
数据重用与合并
为了保持内容的简洁,避免过多重复的定义,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
锚点必须加在冒号后,值之前,然后用*符号可以解引用
配合合并标签“<<”使用可以与任意数据进行合并,你可以把这套操作想象成面向对象语言中的继承
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语法的注意事项
简单概括下几点在YAML型配置文件中需要注意的点:
(1)使用空格进行缩进
(2)用单引号包装正则表达式
不是必须,但是最好使用单引号,解决YAML针对字符串转义的棘手规则。
(3)用单引号包裹路径
(4)避免在数值使用前导零
如果09在数字字段中使用前盗铃(例如 ,)而不讲值包装在单引号中,则YAML解析器可能会错误地解析该值。
要防止不需要的类型转换,请避免在字段值中使用前导零,或将值包装在单引号中。
以上是关于学好 Yaml的主要内容,如果未能解决你的问题,请参考以下文章