YAML

参考地址:


本文部分来自菜鸟驿站

编程免不了要写配置文件,怎么写配置也是一门学问。

YAML 是专门用来写配置文件的语言,非常简洁和强大,远比 JSON 格式方便。

YAML 是 “YAML Ain’t a Markup Language”(YAML 不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言)。

YAML 的语法和其他高级语言类似,并且可以简单表达清单、散列表,标量等数据形态。它使用空白符号缩进和大量依赖外观的特色,特别适合用来表达或编辑数据结构、各种配置文件、倾印调试内容、文件大纲(例如:许多电子邮件标题格式和YAML非常接近)。

YAML 的配置文件后缀为 .yml,如:xxx.yml
ps:.yaml.yml 文件扩展名在 YAML 文件中是等效的,可以互相替代使用。它们都表示 YAML(YAML Ain’t Markup Language)格式的文件。


基本语法

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进不允许使用tab只允许空格
  • 缩进的空格数不重要,只要相同层级的元素左对齐即可
  • '#'表示注释


数据类型

YAML 支持以下几种数据类型:

  • 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
  • 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
  • 纯量(scalars):单个的、不可再分的值


YAML 对象

对象键值对使用冒号结构表示 key: value,冒号后面要加一个空格。

也可以使用 key:{key1: value1, key2: value2, …}

还可以使用缩进表示层级关系;

1
2
3
key: 
child-key: value
child-key2: value2

较为复杂的对象格式,可以使用问号加一个空格代表一个复杂的 key,配合一个冒号加一个空格代表一个 value:

1
2
3
4
5
6
?  
- complexkey1
- complexkey2
:
- complexvalue1
- complexvalue2

意思即对象的属性是一个数组 [complexkey1,complexkey2],对应的值也是一个数组 [complexvalue1,complexvalue2]



YAML 数组

- 开头的行表示构成一个数组:

1
2
3
- A
- B
- C

YAML 支持多维数组,可以使用行内表示:

1
key: [value1, value2, ...]

数据结构的子成员是一个数组,则可以在该项下面缩进一个空格。

1
2
3
4
-
- A
- B
- C

一个相对复杂的例子:

1
2
3
4
5
6
7
8
9
companies:
-
id: 1
name: company1
price: 200W
-
id: 2
name: company2
price: 500W

意思是 companies 属性是一个数组,每一个数组元素又是由 id、name、price 三个属性构成。

数组也可以使用流式(flow)的方式表示:

1
companies: [{id: 1,name: company1,price: 200W},{id: 2,name: company2,price: 500W}]


复合结构

数组和对象可以构成复合结构,例:

1
2
3
4
5
6
7
8
9
languages:
- Ruby
- Perl
- Python
websites:
YAML: yaml.org
Ruby: ruby-lang.org
Python: python.org
Perl: use.perl.org

转换为 json 为:

1
2
3
4
5
6
7
8
9
{ 
languages: [ 'Ruby', 'Perl', 'Python'],
websites: {
YAML: 'yaml.org',
Ruby: 'ruby-lang.org',
Python: 'python.org',
Perl: 'use.perl.org'
}
}


纯量

纯量是最基本的,不可再分的值,包括:

  • 字符串
  • 布尔值
  • 整数
  • 浮点数
  • 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连接,最后使用+代表时区


引用

& 锚点和 * 别名,可以用来引用:

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

相当于:

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

development:
database: myapp_development
adapter: postgres
host: localhost

test:
database: myapp_test
adapter: postgres
host: localhost

& 用来建立锚点(defaults),<< 表示合并到当前数据,***** 用来引用锚点。

下面是另一个例子:

1
2
3
4
5
- &showell Steve 
- Clark
- Brian
- Oren
- *showell

转为 JavaScript 代码如下:

1
[ 'Steve', 'Clark', 'Brian', 'Oren', 'Steve' ]




YAML在python中运用

pyyaml库

Python的PyYAML模块是Python的YAML解析器和生成器。

安装

1
pip install pyyaml


yaml.safe_load()

当使用 PyYAML 处理 YAML 数据时,safe_load() 函数是推荐的加载函数,因为它限制了可以被加载的 Python 对象类型,提高了安全性。以下是关于 safe_load() 函数的详细介绍:

safe_load() 函数:

  • yaml.safe_load(stream): 该函数用于从 YAML 格式的输入流中加载数据。它限制了可以被加载的 Python 对象类型,以减少潜在的安全风险。

示例:

当将 YAML 数据放在名为 demo.yml 的文件中时,我们可以使用 safe_load() 函数从该文件中加载数据。以下是基于这一情境的示例代码:

demo.yml文件内容:

1
2
3
4
5
6
7
8
user:
name: John Doe
age: 25
email: john@example.com

preferences:
theme: dark
language: python

load.py文件代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import yaml

def load_yaml(file_path):
with open(file_path, 'r') as file:
data = yaml.safe_load(file)
return data

if __name__ == "__main__":
file_path = "demo.yml"
yaml_data = load_yaml(file_path)

# 示例:访问 YAML 数据
user_name = yaml_data['user']['name']
user_age = yaml_data['user']['age']
preferences_theme = yaml_data['preferences']['theme']

print(f"User: {user_name}, Age: {user_age}")
print(f"Preferences - Theme: {preferences_theme}")
查看输出
1
2
User: John Doe, Age: 25
Preferences - Theme: dark

在这个示例中,我们使用 open() 函数打开 demo.yaml 文件,然后将文件对象传递给 yaml.safe_load() 函数,以加载 YAML 数据。接着,我们通过字典的方式访问加载后的数据,并打印了一些示例信息。


注意事项:

  • 尽管 safe_load() 增加了安全性,但仍然建议在处理来自不受信任源的 YAML 数据时谨慎操作。


yaml.dump()

yaml.dump() 函数是 PyYAML 库中用于将 Python 对象转换为 YAML 格式的函数。它可以将 Python 对象序列化为 YAML 文本,以便进行存储或传输。

以下是 yaml.dump() 函数的基本用法:

1
2
3
4
5
6
7
8
9
10
import yaml

# Python 对象
data = {'name': 'John', 'age': 30, 'scores': [85, 90, 78]}

# 将 Python 对象转换为 YAML 文本
yaml_text = yaml.dump(data)

# 输出 YAML 文本
print(yaml_text)

上述代码将 Python 字典 data 转换为相应的 YAML 文本。输出结果可能类似于:

1
2
3
4
5
6
yamlCopy codeage: 30
name: John
scores:
- 85
- 90
- 78

yaml.dump() 函数还支持一些可选参数,允许你自定义输出的格式。以下是一些常用的参数:

  • default_flow_style 控制输出是否使用流式样式。默认为 True,表示使用流式样式,如果设置为 False,则输出为块样式。

    1
    yaml_text = yaml.dump(data, default_flow_style=False)
  • indent 控制缩进的空格数。默认为 2

    1
    yaml_text = yaml.dump(data, indent=4)
  • width 控制每行的最大宽度。默认为 None,表示不限制宽度。

    1
    yaml_text = yaml.dump(data, width=50)

这些参数可以根据你的需求进行调整,以生成符合特定要求的 YAML 文本。yaml.dump() 函数的灵活性使得在将 Python 对象导出为 YAML 格式时具有很好的定制性。



实际

实际生产中……

在实际项目中,使用 YAML 通常用于配置文件、数据存储或其他需要人类可读和编辑的结构化数据。以下是一些实际项目中使用 YAML 的常见场景和用法:

  1. 配置文件: YAML 文件常用于存储应用程序的配置参数。例如,数据库连接信息、日志设置、应用程序行为的默认值等可以作为 YAML 配置文件存储。

    1
    2
    3
    4
    5
    6
    7
    8
    # config.yaml
    database:
    host: localhost
    port: 5432
    username: user
    password: pass
    log:
    level: info

    在应用程序中,你可以使用 PyYAML 将配置加载到 Python 字典中,然后在代码中访问这些配置。

  2. 数据序列化: YAML 适用于序列化和反序列化数据。你可以使用 YAML 将复杂的数据结构(如字典、列表等)保存到文件,然后再次加载它们。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    import yaml

    data = {'name': 'John', 'age': 30, 'scores': [85, 90, 78]}

    # 将数据保存到 YAML 文件
    with open('data.yaml', 'w') as file:
    yaml.dump(data, file)

    # 从 YAML 文件加载数据
    with open('data.yaml', 'r') as file:
    loaded_data = yaml.safe_load(file)
  3. 定义任务流程: YAML 文件可以用于定义工作流程、任务流程或管道。在某些情况下,你可能会使用 YAML 文件来描述不同阶段的任务和其依赖关系。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # workflow.yaml
    stages:
    - name: build
    tasks:
    - compile
    - test
    - name: deploy
    tasks:
    - deploy_to_production

    这样的文件可以在自动化工具或流程管理系统中使用,确保任务按预期顺序执行。

  4. API文档: YAML 也用于编写和存储 API 文档。你可以使用 YAML 文件定义 API 端点、请求和响应的结构,以及其他相关信息。

    1
    2
    3
    4
    5
    # api_documentation.yaml
    endpoints:
    - path: /users
    methods: [GET, POST, PUT, DELETE]
    description: Operations related to users

    这种方式可以使 API 文档更易读、易写,并且可以通过工具自动生成文档。

  5. Docker Compose 文件: 在容器化应用中,Docker Compose 使用 YAML 文件定义多个服务、网络和卷的配置。这种配置方式使得容器化应用的部署和管理更为简单。

    1
    2
    3
    4
    5
    6
    version: '3'
    services:
    web:
    image: nginx:latest
    ports:
    - "8080:80"

    上述是一个简单的 Docker Compose 文件,用于定义一个运行 Nginx 服务的容器。

这只是一些在实际项目中使用 YAML 的例子,实际应用中可能涉及更多方面。总体来说,YAML 提供了一种清晰、可读的文本格式,适用于各种配置和数据表示的场景。在 Python 中,使用 PyYAML 库可以方便地处理和操作 YAML 数据。





YAML在web中使用

一般要借助JavaScript来实现,下面都采用JavaScript的一个库——js-yaml
nodeca/js-yaml: JavaScript YAML parser and dumper. Very fast. (github.com)



在浏览器环境中使用 js-yaml

1
2
<!-- 引入 js-yaml 库 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-yaml/4.0.0/js-yaml.min.js"></script>


在node.js环境中使用js-yaml

1
npm install js-yaml