yaml基本语法
yaml在python的使用
pyyaml
yaml概述
YAML(YAML Ain't Markup Language)是一种标记语言(Yet Another Markup Language),是一种较为人性化的数据序列化语言,可以配合目前大多数编程语言使用。
YAML 的语法比较简洁直观,特点是使用空格来表达层次结构,其最大优势在于数据结构方面的表达,所以 YAML 更多应用于编写配置文件,且比JSON 格式更加简洁方便。
yaml官方文档
yaml基本语法
yaml编写规则
- 使用
#
注释 - 区分大小写
- 大小写敏感
- 使用缩进表示层级关系
- 缩进格式:使用空格缩进,非TAB键。空格数目不固定,相同层级一致即可
# 这是yaml注释
one:
One: 1 # 大小写敏感
three:
four: 4
five: 5 # 相同层级缩进一致
等效json:
{
"one":{
"One":1,
"three":{
"four":4,
"five":5
}
}
}
显然YAML要简洁很多,不需要大括号、不需要引号
接下来介绍yaml常见数据类型,由于对json比较熟悉,接下来通过将常用json字符串转换成yaml
数组
一组按次序排列的值,又称为序列(sequence) / 列表(list)
- 一维数组
对应的yaml为:["jerry", 28, "shanghai"]
- jerry - 28 - shanghai
- 多维数组
对应的yaml为:[ [ "jerry", 28, "shanghai" ], [ "tom", 26, "beijing" ] ]
- - jerry - 28 - shanghai - - tom - 26 - beijing
注:
-
后必须有空格
对象
键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
key: value
对应的yaml为:{ "name": "jerry", "age": 28, "address": "shanghai" }
name: jerry age: 28 address: shanghai
- 多层嵌套
对应的yaml为:{ "name": "jerry", "age": 28, "address": "shanghai", "friend": { "boyfriend": "tom", "girlfriend": "lily" } }
name: jerry age: 28 address: shanghai friend: boyfriend: tom girlfriend: lily
注:
-
后必须有空格
数组与对象组合
- 对象嵌套数组
对应yaml为:{"name": "jerry", "age": 28, "language":["java","golang","python"], "other_info": ["address": "shanghai", "boyfriend": "tom"]}
name: jerry age: 28 language: - java - golang - python other_info: - address: shanghai - boyfriend: tom
- 数组嵌套对象
对应的yaml为:[{"name": "jerry"}, {"age": 28}, {"address": "shanghai", "girlfriend": "lily"}, {"salary": 99999, "pet": "bingo"}]
- name: jerry - age: 28 - address: shanghai girlfriend: lily - salary: 99999 pet: bingo
纯量
纯量(scalars) : 单个的、不可再分的值
字符串、整数、浮点数、Null、布尔值、时间、日期
- 字符串
字符串一般不需要用引号包裹,但是如果字符串中使用了反斜杠“\
”开头的转义字符就必须使用引号包裹info: - monkey jerry # 不用引号包裹 - monkey jerry # 拆成多行后会自动在中间添加空格 - 'monkey jerry' # 单引号包裹 - "welcome to jerry's blog" # 双引号包裹 - 'I said: "hello, monkey jerry"' # 单双引号支持嵌套 - "monkey jerry. \u263A" # 使用双引号包裹时支持 Unicode 编码 - "\x0d\x0a is \r\n" # 使用双引号包裹时还支持 Hex 编码
- 整数和浮点数
对应的yaml为:{"age": 28, "salary": 99999.9}
age: 28 salary: 99999.9
- 空
对应的yaml{ "nulls": [null, null, null, null] }
nulls: - null - Null - ~ -
“null”、“Null”和“~”都是空,不指定值默认也是空
- 布尔值
对应的yaml为:{ "boolean": [true, true, false, false] }
boolean: - true # True、TRUE - yes # Yes、YES - false # False、FALSE - no # No、NO
- “true”、“True”、“TRUE”、“yes”、“Yes”和“YES”皆为真
- “false”、“False”、“FALSE”、“no”、“No”和“NO”皆为假
- 时间和日期
time: 2019-09-03t01:00:05 date: 2019-09-03
数据重用和合并
- 建立锚点
&
和引用锚点*
为了保持内容的简洁,避免过多重复的定义,YAML 提供了由锚点标签“&”和引用标签“*”组成的语法来快速引用相同的数据
对应的yaml可表示为:{ "jerry": {"age": 28, "address": "shanghai"}, "tom": {"age": 28, "address": "shanghai"}}
jerry: &info # &设置锚点 age: 28 address: shanghai tom: *info # *引用锚点
- 合并
<<
配合合并标签“<<”使用可以与任意数据进行合并,你可以把这套操作想象成面向对象语言中的继承
对应的yaml可表示为:{ "jerry": {"age": 28, "address": "shanghai"}, "tom": {"age": 28, "address": "shanghai", "skill": "python"}, "lily": {"age": 28, "address": "beijing", "skill": "golang"}}
jerry: &info # 设置锚点 age: 28 address: shanghai tom: <<: *info # 引用锚点,实例化时会自动展开 skill: python # 添加额外的属性 lily: <<: *info # 引用锚点 address: beijing # 覆盖锚点中的属性 skill: golang
yaml在python的使用
pyyaml
- 安装
pip install pyyaml
- 官方文档
pyyaml 官方文档
在python中使用
更多关于pyyaml在python中的特性请参看以上官方文档,这里仅介绍个人常用
如下data.yaml文件(可理解为配置文件):
info:
basic_info:
name: jerry
age: 28
other_info:
address: shanghai
salary: 99999
- 使用yaml.safe_load获取jerry的工资:
import yaml with open("data.yaml") as f: yaml_data = f.read() info = yaml.safe_load(yaml_data) print(type(info)) print(info) jerry_salary = info['info']['other_info']['salary'] print(jerry_salary) ----------------------------------------- <class 'dict'> {'info': {'basic_info': {'name': 'jerry', 'age': 28}, 'other_info': {'address': 'shanghai', 'salary': 99999}}} 99999
- 修改jerry的地点为beijing后并存入新的yaml文件(yaml.safe_dump):
import yaml with open("data.yaml") as f: yaml_data = f.read() info = yaml.safe_load(yaml_data) info['info']['other_info']['address'] = 'beijing' with open("new_data.yaml", "w") as f: f.write(yaml.dump(info))
- 使用yaml处理json
YAML是JSON的超集,所以解析YAML的程序也能正常解析JSON格式
data.yaml
数据对应的data.json
可表示为:
用1中的程序处理:{"info":{"basic_info":{"name":"jerry","age":28},"other_info":{"address":"shanghai","salary":99999}}}
import yaml with open("data.json") as f: yaml_data = f.read() info = yaml.safe_load(yaml_data) print(type(info)) print(info) jerry_salary = info['info']['other_info']['salary'] print(jerry_salary)
运行以上程序,可以看出实现了相同的效果