目录

  1. yaml 语法及用python读取文件内容
    1. 0 背景
      1. 1 什么是yaml
      2. 2 学习参考网址
      3. 3 yaml 优缺点
    2. 1 语法
      1. 基本语法规则
      2. 数据结构
      3. 附加
      4. 语法详细示例解析
        1. 1 对象
        2. 2 数组
        3. 3 复合结构
        4. 4 纯量
        5. 5 其他用法:引用
    3. 2 python读取
      1. 1 使用 python 仅读取
      2. 2 读取后传入 pytest/unittest 中进行参数化

yaml 语法及用python读取文件内容

0 背景

1 什么是yaml

先看一下官网是如何介绍的

What It Is:
YAML is a human-friendly data serialization
language for all programming languages.

YAML 是一种对人类友好的数据序列化语言,所有的编程语言都可以使用

YAML 主要用于写配置文件,是一种来写配置文件的语言。例如 docker-compose.yml

文件名以 .yml 结尾

2 学习参考网址

官网网址:https://yaml.org/

官方文档:https://yaml.org/spec/1.2.2/

阮一峰YAML教程网站:https://ruanyifeng.com/blog/2016/07/yaml.html

3 yaml 优缺点

yaml与json相比的优点

1 yaml可以添加注释 (通过 # ),json无法添加注释。

2 在格式上json的要求更为严格。

例如字符串格式在json中必须在其左右加上双引号,而 ymal 则是可以去掉字符串左右的双引号的,除非特意强调某一串数字是字符串格式等类似情况;

在布尔值上,json 有着较为严格的要求,只能是 truefalse 这两种格式。而在yaml中,true / Truefalse / False 都属于正确的格式。

在作为配置文件的使用上,yaml可以看做是json配置文件的升级。

1 语法

YAML 和 Python 某些语法规则上是相似的,对 缩进空格 格式上要求严格,数据类型不敏感

基本语法规则

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进时不允许使用 Tab 键,只允许使用空格
  • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可

数据结构

对象:键值对的集合,又称为 映射 (mapping) / 哈希 (hashes) / 字典 (dictionary)

数组:一组按次序排列的值,又称为 序列 (sequence) / 列表 (list)

纯量 (scalars) :单个的、不可再分的值

附加

# 表示注释

语法详细示例解析

1 对象

  • 基础格式,冒号后必须要加上空格
1
key: value
  • 多层级关系
1
2
3
key: 
child-key1: value1
child-key2: value2

python中格式转化后:

1
{'key': {'child-key1': 'value1', 'child-key2': 'value2'}}

对象格式的另一种写法,行内表示法

1
hash: { name: Steve, foo: bar } 

python中格式转化后:

1
{'hash': {'name': 'Steve', 'foo': 'bar'}}
  • 复杂对象格式 (yaml1.2.1版本文档中提到了此用法)

问号 (?) 后加上一个空格表示一个复杂的key;冒号 (:) 后加一个空格表示一个value

1
2
3
4
5
6
? 
- complex-key1
- complex-key2
:
- complex-value1
- complex-value2

2 数组

  • 基础格式, - 后必须要加上空格
1
2
3
- arr1
- arr2
- arr3
  • 多维数组
1
2
3
4
5
6
7
8
-
- arr1
- arr2
- arr3
-
- arr4
- arr5
- arr6

python中格式转化后:

1
[['arr1', 'arr2', 'arr3'], ['arr4', 'arr5', 'arr6']]

行内表示法

1
[arr1, arr2, arr3]

在python中格式转化后:

1
['arr1', 'arr2', 'arr3']

3 复合结构

复合结构指的是对象和数组可以结合在一起进行使用

1
2
3
4
5
6
key1: 
- arr1
- arr2
- arr3
key2:
key2-1: value2-1

在 python 中格式转化后:

1
{'key1': ['arr1', 'arr2', 'arr3'], 'key2': {'key2-1': 'value2-1'}}

4 纯量

字符串

布尔值

整数

浮点数

null

时间

日期

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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连接,最后使用+代表时区

5 其他用法:引用

重复的节点在yaml中首先设置锚点 & 进行标识,再用星号 * 引用锚点。类比的话类似于python中的 定义变量 和 引用变量。

1
2
3
锚点 &
引用 *
合并到当前数据 <<

例一:使用锚点 &SS 标注纯量 Sammy Sosa*SS 引用锚点

1
2
3
4
5
6
7
hr:
- Mark McGwire
# Following node labeled SS
- &SS Sammy Sosa
rbi:
- *SS # Subsequent occurrence
- Ken Griffey

python 输出

1
{'hr': ['Mark McGwire', 'Sammy Sosa'], 'rbi': ['Sammy Sosa', 'Ken Griffey']}

例二:使用锚点标注数组

1
2
3
4
5
6
7
8
9
- &arr1
- a
- b
- c
-
- d
- e
-
*arr1

python输出

1
[['a', 'b', 'c'], ['d', 'e'], ['a', 'b', 'c']]

例三:使用锚点标注对象

1
2
3
4
5
6
7
8
9
10
11
defaults: &defaults
adapter: postgres
host: localhost

development:
database: myapp_development
<<: *defaults

test:
database: myapp_test
<<: *defaults

python输出

1
2
3
4
5
{
'defaults': {'adapter': 'postgres', 'host': 'localhost'},
'development': {'adapter': 'postgres', 'host': 'localhost', 'database': 'myapp_development'},
'test': {'adapter': 'postgres', 'host': 'localhost', 'database': 'myapp_test'}
}

例四:使用锚点标注复合结构,此例子中标注了复合结构的数组

1
2
3
4
5
6
7
8
9
10
- key1: &key
- arr1
- arr2
- arr3
key2:
key2-1: value2-1
key3:
*key
- key4:
*key

python输出

1
2
3
4
5
[
{'key1': ['arr1', 'arr2', 'arr3'],
'key2': {'key2-1': 'value2-1'},
'key3': ['arr1', 'arr2', 'arr3']},
{'key4': ['arr1', 'arr2', 'arr3']}]

2 python读取

1 使用 python 仅读取

1
2
3
4
5
# 使用 python 仅读取
def read_yaml(filename):
with open(filename, encoding='UTF-8') as f:
data = yaml.load(f, Loader=yaml.FullLoader)
return data

2 读取后传入 pytest/unittest 中进行参数化

1
2
3
4
5
6
7
8
# 读取后传入 pytest 中进行参数化
def read_yaml(filename):
with open(filename, encoding='UTF-8') as f:
data = yaml.load(f, Loader=yaml.FullLoader)
list_tuple = []
for i in data:
list_tuple.append(tuple(i))
return list_tuple

yaml文件示例:

1
2
3
4
5
6
7
8
9
# yaml文件示例
-
- 1
- 2
- 3
-
- 4
- 5
- 9

运行结果:

1
[(1, 2, 3), (4, 5, 9)]