Python 处理 YAML 文件完全指南

用 Python 读写 YAML:PyYAML 基础读写、嵌套数据操作、安全加载、从对象生成 YAML、PyKwalify 校验配置文件合法性。

最佳实践
并发任务的多路径协同插画

直接回答:PyYAML 是需要单独安装的第三方 YAML 库:safe_load 将 YAML 解析为相应 Python 数据,dump 写回;配置修改、批量生成、合法性校验都能几行搞定。 记住一条军规:永远用 safe_load,不用 load。

安装与读取

pip install pyyaml
import yaml

with open("config.yaml", encoding="utf-8") as f:
    config = yaml.safe_load(f)     # 也可能返回标量或空文档的 None

if not isinstance(config, dict) or not isinstance(config.get("database"), dict):
    raise ValueError("配置必须包含 database 映射")
print(config["database"]["host"])

safe_load 只解析纯数据结构;旧版本默认 load 或显式不安全 Loader 可能构造任意 Python 对象;当前 PyYAML 的 load 需要显式 Loader,不能把无 Loader 调用当作当前可运行 API。对于外部配置应优先 safe_load,且仍需结构和资源限制。

YAML 与 Python 类型映射

YAML Python
映射(键值) dict
序列(- 列表) list
字符串/数字/布尔 str/int/float/bool
null / ~ None
日期 datetime.date

修改与写回

config["database"]["pool_size"] = 20
config["features"].append("new-ui")

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

三个实用参数:allow_unicode=True(中文不转义)、sort_keys=False(保持原有键序)、default_flow_style=False(块式输出更人读)。

从零生成 YAML

deploy = {
    "version": "1.0",
    "services": [
        {"name": "web", "replicas": 3, "ports": [80, 443]},
        {"name": "worker", "replicas": 2},
    ],
}

with open("deploy.yaml", "w", encoding="utf-8") as f:
    yaml.safe_dump(deploy, f, allow_unicode=True, sort_keys=False)

嵌套列表与字典按数据结构原样生成——批量产出 K8s 清单、CI 配置的自动化脚本就靠它。

校验:PyKwalify

先安装 pykwalify。YAML 解析检查语法,Schema 再检查结构和约束。下面的独立校验示例只允许 database 配置;真实配置若包含 features 等键,也要在 schema 中声明:

from pykwalify.core import Core

config = {"database": {"host": "localhost", "port": 5432}}

schema = """
type: map
mapping:
  database:
    required: True
    type: map
    mapping:
      host: {type: str, required: True}
      port: {type: int, range: {min: 1, max: 65535}}
"""

core = Core(source_data=config, schema_data=yaml.safe_load(schema))
core.validate()    # 不合法直接抛异常,指明字段与原因

启动时先校验配置再初始化——"配置错误启动即报"比"运行半小时后诡异崩溃"仁慈太多。

工程实践

  • 注释与格式:PyYAML dump 会丢注释。要保留注释的读写用 ruamel.yaml;
  • 多文档:safe_load_all 处理 --- 分隔的多文档文件(K8s 清单常见);
  • 环境变量:YAML 不支持插值,常见做法是读入后应用层替换 ${VAR} 占位符。

常见问题(FAQ)

Q:PyYAML 和 ruamel.yaml 怎么选?
A:纯读写配置 PyYAML 通常够用;需要保留注释、格式、键序的"改写已有 YAML"场景用 ruamel.yaml。

Q:YAML 和 JSON/TOML 怎么选?
A:人写的配置选 YAML/TOML(注释友好);机器间传输常选 JSON;具体配置格式要符合消费工具的约定,Kubernetes 也可接受 JSON 清单。

Q:safe_load 真的安全吗?
A:safe_load 限制对象构造,但不是对任意不可信输入的资源隔离保证。限制输入大小、结构深度及解析时间,避免后续递归处理别名形成的共享或循环结构;必要时在受限进程处理。

官方参考

本文基于官方文档整理,未进行运行时或性能测试。示例中的业务函数、数据模型和部署地址需结合项目补全;局部片段不等同于完整生产应用。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台