YAML 详解

YAML 详解

文章目录

什么是 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 可以显著提高工作效率和配置文件的维护性。

相关推荐
H Journey10 天前
yaml配置文件使用规则
配置文件·yaml
海棠AI实验室1 个月前
第五章 配置管理:用 YAML/ENV 让项目可迁移
python·yaml
科雷软件测试1 个月前
推荐几个常用的校验yaml、json、xml、md等多种文件格式的在线网站
xml·html·md·yaml
m0_488777651 个月前
Kubernetes基础
云原生·容器·kubernetes·yaml
江上清风山间明月2 个月前
YAML语法详解
语法·yaml
艺杯羹2 个月前
掌握Spring Boot配置艺术:从YAML基础到实战进阶
java·spring boot·后端·yaml
最笨的羊羊2 个月前
Debezium日常分享系列之:认识debezium operator、debezium server yaml格式、部署debezium server
debezium日常分享系列·debezium·yaml·operator·debezium server
行走的陀螺仪2 个月前
什么是yaml文件,使用它的场景有哪些,要怎么执行它
ci/cd·部署·工程化·yaml
I'm Jie3 个月前
从零开始学习 TOML,配置文件的新选择
python·properties·yaml·toml