随着互联网技术的快速发展,服务器编程变得越来越重要。Python作为一种强大的编程语言,越来越受到开发者的青睐。而PyYAML则是Python中最常用的YAML格式解析器之一,本文将系统介绍yaml知识

01yaml介绍

YAML(YAML Ain't Markup Language)是一种直观的数据序列化格式,它旨在以易于人类阅读和编写的方式表达数据。尽管名称中包含“不是标记语言”的表述,YAML在实际应用中经常被视为一种标记语言,因为它通过特定的符号和格式来组织和表示数据。YAML的简洁性、可读性和灵活性使其成为配置文件、数据交换、API文档编写等领域的理想选择。

适用场景

  • 配置文件:YAML因其易读性和可写性,非常适合用于存储应用程序的配置信息。相比传统的JSON或XML,YAML的语法更加简洁,易于理解和维护。

  • 数据交换:在微服务架构或分布式系统中,服务之间经常需要交换数据。YAML提供了一种轻量级的数据交换格式,便于不同系统之间传递复杂的数据结构。

  • API文档:YAML也常用于编写API文档,如OpenAPI规范(之前称为Swagger)就支持使用YAML格式来描述RESTful API的接口定义。

语法规则

  • 大小写敏感:YAML中的键(key)是大小写敏感的。

  • 缩进:YAML使用空格(通常是两个或四个空格)来表示层级关系,不允许使用Tab键。同一层级的元素必须左对齐。

  • 注释:以#开头的行被视为注释,解析器会忽略这些行。

  • 数据类型:YAML支持多种数据类型,包括对象(键值对)、数组(列表)、纯量(如字符串、数字、布尔值等)。

  • 特殊字符:YAML中的某些特殊字符(如冒号:、短横线-)具有特定含义,使用时需要注意。

02三种数据结构

1、对象(Map/Dictionary)

对象由键值对组成,每个键值对之间用冒号加空格分隔,多个键值对之间用换行符分隔。

实例

person:  
  name: 张三  
  age: 30  
  is_student: false

或者使用行内表示法:

person: {name: 张三, age: 30, is_student: false}

2、数组(Sequence/List)

数组是一组有序的值,每个值之前使用短横线加空格表示。

实例:​​​​​​​

hobbies:  
  - 游泳  
  - 跑步  
  - 读书

或者使用行内表示法:

hobbies: [游泳, 跑步, 读书]

3、纯量(Scalar)

纯量是YAML中最基本的数据类型,包括字符串、数字、布尔值等。

实例:​​​​​​​

string: Hello, YAML!  
integer: 123  
float: 3.14  
boolean: true  
null: ~ # YAML中使用~来表示null值,也可以使用null或Null(大小写敏感)

03yaml安装使用

1)安装PyYAML

首先,你需要安装PyYAML库。可以使用pip进行安装:

pip install PyYAML

2)读取yaml文件​​​​​​​

import yaml  
  
with open('data.yaml', 'r', encoding='utf-8') as file:  
    data = yaml.safe_load(file)  
  
print(data)

3)写入yaml文件​​​​​​​

import yaml  
  
data = {  
    'person': {  
        'name': '李四',  
        'age': 28,  
        'is_student': False  
    },  
    'hobbies': ['编程', '旅行', '音乐']  
}  
  
with open('output.yaml', 'w', encoding='utf-8') as file:  
    yaml.dump(data, file, allow_unicode=True, default_flow_style=False)

在上面的写入示例中,allow_unicode=True参数允许YAML文件中包含Unicode字符,default_flow_style=False参数确保输出使用块式(block)风格而不是流式(flow)风格,从而使输出的YAML文件更易于阅读。

04读取多个yaml 文档

1. 多个文档在一个yaml文件,使用 --- 分隔方式来分段

如:yaml文件中数据​​​​​​​

# 分段yaml文件中多个文档
---
animal1: dog
age: 2
---
animal2: cat
age: 3

2. python脚本读取一个yaml文件中多个文档方法

python获取yaml数据时需使用load_all函数来解析全部的文档,再从中读取对象中的数据​​​​​​​

# yaml文件中含有多个文档时,分别获取文档中数据
def get_yaml_load_all(yaml_file):
    # 打开yaml文件
    file = open(yaml_file, 'r', encoding="utf-8")
    file_data = file.read()
    file.close()
    all_data = yaml.load_all(file_data)
    for data in all_data:
        print(data)
current_path = os.path.abspath(".")
yaml_path = os.path.join(current_path, "config.yaml")
get_yaml_load_all(yaml_path)
"""结果
{'animal1': 'dog', 'age': 2}
{'animal2': 'cat', 'age': 3}
"""

05生成yaml文档

1. 直接导入yaml(即import yaml)生成的yaml文档

通过yaml.dump()方法不会将列表或字典数据进行转化yaml标准模式,只会将数据生成到yaml文档中​​​​​​​

# 将python对象生成yaml文档
import yaml
def generate_yaml_doc(yaml_file):
    py_object = {'school': 'zhang',
                 '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: zhang
students: [a, b]
"""

2. 使用ruamel模块中的yaml方法生成标准的yaml文档

(1)使用ruamel模块中yaml前提条件

  • 使用yaml需要安装的模块:ruamel.yaml(pip3 install ruamel.yaml);

  • 导入的模块:from ruamel import yaml

(2)ruamel模块生成yaml文档​​​​​​​

def generate_yaml_doc_ruamel(yaml_file):
    from ruamel import yaml
    py_object = {'school': 'zhang',
                 '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: zhang
students:
- a
- b
"""

(3)ruamel模块读取yaml文档​​​​​​​

# 通过from ruamel import yaml读取yaml文件
def get_yaml_data_ruamel(yaml_file):
    from ruamel import yaml
    file = open(yaml_file, 'r', encoding='utf-8')
    data = yaml.load(file.read(), Loader=yaml.Loader)
    file.close()
    print(data)
current_path = os.path.abspath(".")
yaml_path = os.path.join(current_path, "dict_config.yaml")
get_yaml_data_ruamel(yaml_path)

更多推荐