Python PyYAML模块详解:语法、数据结构与实战应用
本文深入解析Python中PyYaml模块的核心用法,涵盖YAML基础语法、三种数据结构及load/dump等关键API。通过实例演示如何将Python对象序列化为YAML文档,并对比ruamel模块在生成标准YAML时的优势,帮助开发者高效处理配置文件。
YAML基础概念与PyYaml简介
一、YAML是什么
YAML(Yet Another Markup Language)是专为编写配置文件设计的语言,其便捷性远超JSON格式。
该语言的设计初衷即在于提升人类读写文件的效率与体验。
作为一种比XML和JSON更轻量、简洁且功能强大的文件格式,YAML通过缩进层级来表现数据结构,这种特性与Python语言的风格高度契合。
顾名思义,由YAML语法编写的文件即称为YAML文件。PyYaml是Python中专门用于操作YAML文件的第三方库,其接口设计简洁易用。
安装 pip install pyyaml # 如果是py2,使用 pip install yaml
PyYaml核心API实战:load与dump
二、PyYaml的简单使用
其使用方式与json、pickle等库类似,主要依赖load和dump两个核心函数即可完成大部分操作。
load()示例:返回一个对象
import yaml
yaml_str = """
name: 一条大河
age: 1956
job: Singer
"""
y = yaml.load(yaml_str, Loader=yaml.SafeLoader)
print(y)
运行结果:
{'name': '一条大河', 'age': 1956, 'job': 'Singer'}
load_all()示例:生成一个迭代器
若字符串或文件包含多个YAML文档块,可使用yaml.load_all来逐一解析所有文档。
yaml_test.yaml文件内容:
---
name: qiyu
age: 20岁
---
name: qingqing
age: 19岁
操作yaml文件的test.py文件如下:
import yaml
with open("./yaml_test", 'r', encoding='utf-8') as ymlfile:
cfg = yaml.load_all(ymlfile, Loader=yaml.SafeLoader)
for data in cfg:
print(data)
运行结果:
{'name': 'qiyu', 'age': '20岁'} {'name': 'qingqing', 'age': '19岁'}
dump()示例:将一个python对象生成为yaml文档
import yaml
json_data = {'name': '一条大河',
'age': 1956,
'job': ['Singer','Dancer']}
y = yaml.dump(json_data, default_flow_style=False).encode('utf-8').decode('unicode_escape')
print(y)
运行结果:
age: 1956 job: - Singer - Dancer name: "一条大河"
向dump()传入文件句参,可直接将内容写入yaml文件:
import yaml
json_data = {'name': '一条大河',
'age': 1956,
'job': ['Singer', 'Dancer']}
with open('./yaml_write.yaml', 'w') as f:
y = yaml.dump(json_data, f)
print(y)
写入内容后的yaml_write.yaml:

yaml.dump_all()示例:将多个段输出到一个文件中
import yaml
obj1 = {"name": "river", "age": 2019}
obj2 = ["Lily", 1956]
obj3 = {"gang": "ben", "age": 1963}
obj4 = ["Zhuqiyu", 1994]
with open('./yaml_write_all.yaml', 'w', encoding='utf-8') as f:
y = yaml.dump([obj1, obj2, obj3, obj4], f)
print(y)
with open('./yaml_write_all.yaml', 'r') as r:
y1 = yaml.load(r, Loader=yaml.SafeLoader)
print(y1)
写入内容后的yaml_write_all.yaml:

为什么写入文件后的格式有的带1个“-”,有的带2个“-”?
为什么yaml文件读出来的的格式是List?
YAML语法规则与数据结构详解
三、YAML的语法规则和数据结构
通过上述4个简单示例,现在来总结YAML语言的基本语法规范。
YAML 基本语法规则如下:
1、大小写敏感
2、使用缩进表示层级关系
3、缩进时不允许使用Tab键,只允许使用空格。
4、缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
5、# 表示注释,从这个字符一直到行尾,都会被解析器忽略,这个和python的注释一样
6、列表里的项用"-"来代表,字典里的键值对用":"分隔
了解了语法规则,现在来回答前文提出的2个问题:
1、带1个“-”表示不同的模块(单个数组或者字典),带2个“-”是因为数组中元素以“-”开始,加上表示不同模块的那一个“-”,呈现出来就是2个“-”
2、因为yaml文件中包含多个模块(多个数组或者字典),读取出来的是这些模块的一个集合
3、有且只有当yaml文件中只有1个字典时,读取出来的数据的类型也是字典
YAML 支持的数据结构有3种:
1、对象:键值对的集合
2、数组:一组按次序排列的值,序列(sequence) 或 列表(list)
3、纯量(scalars):单个的、不可再分的值,如:字符串、布尔值、整数、浮点数、Null、时间、日期
支持数据示例:
yaml_test_data.yaml的内容:
str: "Big River" #字符串
int: 1548 #整数
float: 3.14 #浮点数
boolean: true #布尔值
None: null # 也可以用 ~ 号来表示 null
time: '2019-11-20T08:47:46.576701+00:00' # 时间,ISO8601
date: 2019-11-20 16:47:46.576702 # 日期
操作代码:
import yaml
import datetime
import pytz
yaml_data = {
"str": "Big River",
"int": 1548,
"float": 3.14,
'boolean': True,
"None": None,
'time': datetime.datetime.now(tz=pytz.timezone('UTC')).isoformat(),
'date': datetime.datetime.today()
}
with open('./yaml_test', 'w') as f:
y = yaml.dump(yaml_data, f)
print(y)
with open('./yaml_test', 'r') as r:
y1 = yaml.load(r, Loader=yaml.SafeLoader)
print(y1)
控制台输出:

其他语法规则
1、如果字符串没有空格或特殊字符,不需要加引号,但如果其中有空格或特殊字符,就需要加引号了

2、引用
& 和 * 用于引用
name: &name SKP
tester: *name
运行结果:
{'name': 'SKP', 'tester': 'SKP'}
3、强制转换
用 !! 实现
str: !!str 3.14
int: !!int "123"
运行结果:
{'int': 123, 'str': '3.14'}
4、分段
在同一个yaml文件中,可以用“—”3个“-”来分段,这样可以将多个文档写在一个文件中
举例见上述load_all()示例
Python对象生成YAML文档的高级处理
四、python对象生成yaml文档
1、yaml.dump()方法
import yaml
import os
def generate_yaml_doc(yaml_file):
py_object = {'school': 'zhu',
'students': ['a', 'b']}
file = open(yaml_file, 'w', encoding='utf-8')
yaml.dump(py_object, file)
file.close()
current_path = os.path.abspath(".")
yaml_path = os.path.join(current_path, "generate.yaml")
generate_yaml_doc(yaml_path)
"""结果
school: zhu
students:
- a
- b
"""
2、使用ruamel模块中的yaml方法生成标准的yaml文档
import os
from ruamel import yaml # pip3 install ruamel.yaml
def generate_yaml_doc_ruamel(yaml_file):
py_object = {'school': 'zhu',
'students': ['a', 'b']}
file = open(yaml_file, 'w', encoding='utf-8')
yaml.dump(py_object, file, Dumper=yaml.RoundTripDumper)
file.close()
current_path = os.path.abspath(".")
yaml_path = os.path.join(current_path, "generate.yaml")
generate_yaml_doc_ruamel(yaml_path)
"""结果
school: zhu
students:
- a
- b
"""
使用ruamel模块中的yaml方法读取yaml文档(用法与单独import yaml模块一致)
import os
from ruamel import yaml
def get_yaml_data_ruamel(yaml_file):
file = open(yaml_file, 'r', encoding='utf-8')
data = yaml.load(file, Loader=yaml.Loader)
file.close()
print(data)
current_path = os.path.abspath(".")
yaml_path = os.path.join(current_path, "generate.yaml")
get_yaml_data_ruamel(yaml_path)
到此这篇关于Python中Pyyaml模块的使用的文章就介绍到这了,更多相关Python中Pyyaml模块内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









