YAML 详解

文章目录
- [YAML 详解](#YAML 详解)
-
- [什么是 YAML?](#什么是 YAML?)
- 核心特点
-
- [1. 可读性强](#1. 可读性强)
- [2. 语言无关](#2. 语言无关)
- [3. 表达能力强](#3. 表达能力强)
- 基本语法
- 数据类型详细说明
- 注释
- [YAML vs JSON vs XML](#YAML vs JSON vs XML)
- 使用场景
-
- [1. 配置文件](#1. 配置文件)
- [2. CI/CD 配置](#2. CI/CD 配置)
- [3. Kubernetes 配置](#3. Kubernetes 配置)
- 最佳实践
-
- [1. 一致的缩进](#1. 一致的缩进)
- [2. 键命名规范](#2. 键命名规范)
- [3. 避免复杂嵌套](#3. 避免复杂嵌套)
- [4. 使用引用减少重复](#4. 使用引用减少重复)
- 常用工具
-
- [1. 验证工具](#1. 验证工具)
- [2. 转换工具](#2. 转换工具)
- [3. 编辑器支持](#3. 编辑器支持)
- 常见陷阱
-
- [1. 缩进错误](#1. 缩进错误)
- [2. 布尔值歧义](#2. 布尔值歧义)
- [3. 数字作为字符串](#3. 数字作为字符串)
- 安全注意事项
-
- [1. 避免执行任意代码](#1. 避免执行任意代码)
- [2. 使用安全加载](#2. 使用安全加载)
什么是 YAML?
YAML(YAML Ain't Markup Language)是一种人类友好的数据序列化语言,专门用于配置文件和数据交换。它比 JSON 更易读,比 XML 更简洁,广泛用于各种编程语言和工具的配置。
核心特点
1. 可读性强
- 使用缩进表示层次结构
- 无需大量标点符号
- 支持自然语言风格的配置
2. 语言无关
- 几乎所有现代编程语言都支持 YAML
- 可以轻松转换为 JSON、XML 等其他格式
3. 表达能力强
- 支持复杂的数据结构
- 包含引用、多行文本等高级特性
基本语法
数据结构
标量(Scalars)
yaml
# 字符串
name: "John Doe"
simple_string: Hello World
number_as_string: '123'
# 数字
age: 30
price: 19.99
scientific: 1.2e+5
# 布尔值
is_active: true
enabled: false
# 空值
middle_name: null
nickname: ~
序列(列表/数组)
yaml
# 短横线表示法
fruits:
- Apple
- Banana
- Orange
# 行内表示法
colors: [Red, Green, Blue]
# 嵌套列表
matrix:
- [1, 2, 3]
- [4, 5, 6]
映射(字典/对象)
yaml
# 基本映射
person:
name: John
age: 30
city: New York
# 行内表示法
car: {make: Toyota, model: Camry, year: 2020}
多行文本
yaml
# 保留换行符(|)
description: |
This is a long description
that spans multiple lines.
Each newline is preserved.
# 折叠为单行(>)
summary: >
This is a summary that
will be folded into a
single line with spaces.
# 保留尾随换行符(|+)
# 删除尾随换行符(|-)
特殊特性
锚点和别名(引用)
yaml
# 定义锚点
defaults: &defaults
adapter: postgres
host: localhost
# 引用锚点
development:
<<: *defaults # 合并映射
database: dev_db
test:
<<: *defaults
database: test_db
多文档支持
yaml
# 用 --- 分隔多个文档
---
server:
port: 8080
host: localhost
---
database:
name: app_db
user: admin
数据类型详细说明
字符串类型
yaml
# 不需要引号(除非有特殊字符)
simple: This is a string
# 需要引号的情况
special: "Text with: colon, and other special chars"
single_quotes: 'Avoid escaping single quotes'' here'
数字类型
yaml
# 整数
decimal: 42
octal: 0o52 # 八进制
hexadecimal: 0x2A # 十六进制
# 浮点数
float: 3.14
infinity: .inf # 无穷大
not_a_number: .NaN
时间类型
yaml
date: 2023-12-25
datetime: 2023-12-25T14:30:00Z
iso_datetime: 2023-12-25T14:30:00+08:00
注释
yaml
# 这是单行注释
key: value # 行内注释
# 多行注释需要每行都用 #
# 这是第二行注释
YAML vs JSON vs XML

示例对比
YAML:
yaml
person:
name: John
age: 30
hobbies:
- reading
- swimming
address:
city: New York
zip: "10001"
JSON:
json
{
"person": {
"name": "John",
"age": 30,
"hobbies": ["reading", "swimming"],
"address": {
"city": "New York",
"zip": "10001"
}
}
}
XML:
xml
<person>
<name>John</name>
<age>30</age>
<hobbies>
<hobby>reading</hobby>
<hobby>swimming</hobby>
</hobbies>
<address>
<city>New York</city>
<zip>10001</zip>
</address>
</person>
使用场景
1. 配置文件
yaml
# Docker Compose 示例
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
db:
image: postgres:13
environment:
POSTGRES_PASSWORD: secret
2. CI/CD 配置
yaml
# GitHub Actions 示例
name: CI Pipeline
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run tests
run: npm test
3. Kubernetes 配置
yaml
# Kubernetes Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
最佳实践
1. 一致的缩进
- 使用 2 个空格(推荐)或 4 个空格
- 不要混用制表符和空格
2. 键命名规范
yaml
# 使用小写和下划线
api_key: "value"
database_name: "prod_db"
3. 避免复杂嵌套
yaml
# 不好
level1:
level2:
level3:
level4:
value: too_deep
# 更好(如果可能)
flat_structure:
level1_level2_level3_level4_value: data
4. 使用引用减少重复
yaml
# 定义通用配置
common_settings: &common
timeout: 30
retries: 3
# 复用
service_a:
<<: *common
endpoint: "/api/a"
service_b:
<<: *common
endpoint: "/api/b"
常用工具
1. 验证工具
- yamllint: YAML 语法检查器
- yq: YAML 的 jq(命令行处理工具)
2. 转换工具
bash
# YAML 转 JSON
python -c 'import yaml, json, sys; print(json.dumps(yaml.safe_load(sys.stdin)))' < file.yaml
# JSON 转 YAML
python -c 'import yaml, json, sys; print(yaml.dump(json.load(sys.stdin)))' < file.json
3. 编辑器支持
- VS Code(YAML 扩展)
- IntelliJ IDEA / PyCharm
- Sublime Text
- Vim / Emacs
常见陷阱
1. 缩进错误
yaml
# 错误:混用空格和制表符
data:
key: value # 4个空格
tab: value # 制表符(危险!)
2. 布尔值歧义
yaml
# 这些会被解析为字符串,而不是布尔值
yes_as_bool: yes # 实际是字符串 "yes"
no_as_bool: "no" # 明确字符串
true_as_bool: true # 布尔值 true
3. 数字作为字符串
yaml
# 如果需要将数字保持为字符串,使用引号
zip_code: "10001" # 字符串
postal_code: 10001 # 数字
安全注意事项
1. 避免执行任意代码
yaml
# 危险!某些解析器支持执行代码
danger: !!python/object/apply:os.system ["rm -rf /"]
2. 使用安全加载
python
# Python 示例:使用 safe_load 而不是 load
import yaml
# 安全
data = yaml.safe_load(yaml_content)
# 危险
data = yaml.load(yaml_content, Loader=yaml.Loader)
YAML 的简洁性和可读性使其成为现代开发中不可或缺的工具,特别是在 DevOps、云原生应用和配置管理领域。掌握 YAML 可以显著提高工作效率和配置文件的维护性。