Python 的Yaml用法

YAML简介
YAML(YAML Ain’t Markup Language)即一种反标记(XML)语言。强调数据为中心,而非标记。YAML大小写敏感,使用缩进代表层级关系。

YAML中支持对象Object(对应Python中的字典), 数组Array(对应Python中的列表)以及常量(字符串、数字(int/float),true/false/null)。

相比于JSON格式,YAML免除了双引号,逗号,大括号,中括号等,(当然也支持原始的JSON格式),并且支持注释,类型转换,跨行,锚点,引用及插入等等。

YAML兼容JSON格式,简洁,强大,灵活,可以很方便的构造层级数据并快速转为Python中的字典。

数据及文件通常有三种类型:

  • 配置文件型:如ini,conf,properties文件,适合存储简单变量和配置项,最多支持两层,不适合存储多层嵌套数据
  • 表格矩阵型:如csv,excel等,适合于存储大量同类数据,不适合存储层级结构的数据
  • 多层嵌套型:如XML,HTMl,JSON、YAML,TOML等,适合存储单条或少数多层嵌套数据,不适合存储大量数据

一、安装

需要安装pyyaml
pip install pyyaml

和JSON文件类似,yaml也提供load和dump两种方法。

yaml.load()或yaml.safe_load(YAML字符串或文件句柄):yaml – 字典,如yaml中有中文,需要使用 字符串.encode(‘utf-8′)或打开文件时指定encoding=’utf-8’
yaml.dump(字典):默认为flow流格式,即字典{b’: {‘c’: 3, ‘d’: 4}},会被转为b: {c: 3, d: 4}形式,可以使用default_flow_style=False关闭流模式

由于yaml.load()支持原生Python对象,不安全,建议使用yaml.safe_load()

二、语法

基本规则

  1. 大小写敏感
  2. 使用缩进表示层级关系
  3. 缩进时不允许使用Tab,只允许使用空格
  4. 缩进的空格数目不重要,只要相同层级的元素左对齐即可
  5. # 表示注释,从它开始到行尾都被忽略

yaml转字典

1
2
3
4
# 下面格式读到Python里会是个dict
name: 灰蓝
age: 0
job: Tester

输出

{'name': '灰蓝', 'age': 0, 'job': 'Tester'}

yaml转列表

1
2
3
4
5
# 下面格式读到Python里会是个list
- 灰蓝
- 0
- Tester

输出

['灰蓝', 0, 'Tester']

复合结构

1
2
3
4
5
6
# 下面格式读到Python里是个list里包含dict
- name: 灰蓝
age: 0
job: Tester
- name: James
age: 30

输出

[{'name': '灰蓝', 'age': 0, 'job': 'Tester'}, {'name': 'James', 'age': 30}]

基本类型

  • 字符串
  • 整型
  • 浮点型
  • 布尔型
  • null
  • 时间
  • 日期

这个例子输出一个字典,其中value包括所有基本类型

1
2
3
4
5
6
7
8
9
10
11
12
13
str: "Hello World!"

int: 110

float: 3.141

boolean: true # or false

None: null # 也可以用 ~ 号来表示 null

time: 2016-09-22t11:43:30.20+08:00 # ISO8601,写法百度

date: 2016-09-22 # 同样ISO8601

这里要注意单引号和双引号的区别,单引号中的特殊字符转到Python会被转义,也就是到最后是原样输出了,双引号不会被Python转义,到最后是输出了特殊字符

引用

& 和 * 用于引用

1
2
name: &name 灰蓝
tester: *name

相当于

1
2
name: 灰蓝
tester: 灰蓝

强制转换

yaml是可以进行强制转换的,用 !! 实现

1
2
3
4
5

str: !!str 3.14

int: !!int "123"

输出

{'int': 123, 'str': '3.14'}

分段

在同一个yaml文件中,可以用 — 来分段,这样可以将多个文档写在一个文件中

1
2
3
4
5
6
7
---
name: James
age: 20

---
name: Lily
age: 19

三、使用

pyyaml模块在python中用于处理yaml格式数据,主要使用yaml.safe_dump()、yaml.safe_load()函数将python值和yaml格式数据相互转换。当然也存在yaml.dump()、yaml.load()函数,同样能实现数据转换功能,只是官方不太推荐使用。官方给出的解释,因为yaml.safe_dump()、yaml.safe_load() 能够:

Resolve only basic YAML tags. This is known to be safe for untrusted input.

如果想对一个yaml文件中的多块yaml数据进行转换操作,则可以使用yaml.safe_dump_all()、yaml.safe_load_all()函数。下面会说明yaml.safe_dump()、yaml.safe_load()、yaml.safe_dump_all()、yaml.safe_load_all()函数的用法。

yaml.safe_dump()

1
2
3
4
import yaml
dict_data = {'a': 1, 'b': 2}
with open('data.yaml', 'w', encoding='UTF-8') as yaml_file:
yaml.safe_dump(dict_data, yaml_file)

如果上述yaml.dump()中不带第二个参数,则会返回一个类似yaml格式的字符串

1
2
3
4
5
import yaml
dict_data = {'a': 1, 'b': 2}
yaml_string = yaml.safe_dump(dict_data)
print(type(yaml_string))
print(yaml_string)

运行结果

1
2
3
<class 'str'>
a: 1
b: 2

yaml.safe_load()
将yaml格式文件转换为python值,接第一例子,示例如下:

1
2
3
4
5
import yaml
with open('data.yaml', encoding='UTF-8') as yaml_file:
data = yaml.safe_load(yaml_file)
print(type(data))
print(data)

运行结果:

1
2
<class 'dict'>
{'a': 1, 'b': 2}

yaml.safe_dump_all()
将一序列的python值转换为yaml格式文件,如果yaml.safe_dump_all()中不带第二个参数,则与yaml.dump()类似,会返回一个类似yaml格式的字符串

1
2
3
4
5
6
import yaml
dict_data1 = {'a': 1, 'b': 2}
dict_data2 = {'c': 3, 'd': 4}
yaml_string = yaml.safe_dump_all([dict_data1, dict_data2])
print(type(yaml_string))
print(yaml_string)

运行结果:

1
2
3
4
5
6
<class 'str'>
a: 1
b: 2
---
c: 3
d: 4

yaml.safe_load_all()
将yaml格式文件转换为python值,该yaml文件可以包含多块yaml数据,用法如下:

1
2
3
4
5
import yaml
with open('data.yaml', encoding='UTF-8') as yaml_file:
data = yaml.safe_load_all(yaml_file)
for item in data:
print(item)

运行结果:

1
2
{'a': 1, 'b': 2}
{'c': 3, 'd': 4}

需要注意
1.yml格式中,冒号:后面必须要空一格,否则会解析错误
2.yml文件中,不能出现相同的开头配置名称,只能是树桩结构
3.yml中的特殊符号或空格用单引号或者双引号标记,否则会报找不到文件异常或者特殊符号异常
4.yml不支持tab缩进,必须适应空格缩进,否则会发生错误

Comments

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×