跳到主要内容

YAML 处理

YAML 广泛用于 Kubernetes 清单、Ansible、GitLab CI、Docker Compose。Python 标准库不内置 YAML 解析,推荐使用 PyYAML


安装依赖

在练习项目中执行:

cd ~/python-for-ops
uv add pyyaml

验证:

uv run python -c "import yaml; print(yaml.__version__)"

读取 YAML 字符串

import yaml

manifest = """
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: production
data:
LOG_LEVEL: info
MAX_CONN: "1000"
"""

doc = yaml.safe_load(manifest)
print(doc["kind"]) # ConfigMap
print(doc["metadata"]["namespace"]) # production
print(doc["data"]["LOG_LEVEL"]) # info
注意

解析不可信来源的 YAML 时用 yaml.safe_load,不要用 yaml.load(可能执行任意 Python 对象)。


读写文件

import yaml
from pathlib import Path

path = Path("data/docker-compose.yml")

compose = {
"services": {
"web": {
"image": "nginx:1.25",
"ports": ["8080:80"],
"environment": {"ENV": "prod"},
}
}
}

with path.open("w", encoding="utf-8") as f:
yaml.dump(
compose,
f,
default_flow_style=False,
allow_unicode=True,
sort_keys=False,
)

with path.open(encoding="utf-8") as f:
loaded = yaml.safe_load(f)

print(loaded["services"]["web"]["image"])

allow_unicode=True 保证中文注释与值正常输出;sort_keys=False 保持字段顺序可读。


多文档流(K8s 常见)

一个文件里用 --- 分隔多个资源:

import yaml

multi = """
---
apiVersion: v1
kind: Service
metadata:
name: web-svc
spec:
ports:
- port: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
"""

docs = list(yaml.safe_load_all(multi))
for doc in docs:
print(doc["kind"], doc["metadata"]["name"])
# Service web-svc
# Deployment web

写入多文档用 yaml.dump_all(resources, f, allow_unicode=True, sort_keys=False)


运维场景:批量改 namespace

import yaml
from pathlib import Path

def set_namespace(manifest_path: Path, namespace: str) -> None:
text = manifest_path.read_text(encoding="utf-8")
docs = list(yaml.safe_load_all(text))
for doc in docs:
if doc and "metadata" in doc:
doc.setdefault("metadata", {})["namespace"] = namespace
out = yaml.dump_all(docs, allow_unicode=True, sort_keys=False)
manifest_path.write_text(out, encoding="utf-8")

# 示例:set_namespace(Path("data/app.yaml"), "staging")

小结

场景方法
单文件单资源yaml.safe_load / yaml.dump
多资源清单safe_load_all / dump_all
依赖安装uv add pyyaml

注意:YAML 里 yes/noon/off 可能被解析为布尔值;端口号等建议加引号(如 "8080")。下一章学习 CSV 与 Excel,处理资产表与巡检导出。