You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PyYAML中保留!ENV原标记并保存修改后的配置文件

解决YAML加载替换环境变量但保存保留!ENV标记的问题

核心思路是用自定义类型封装环境变量标记:加载时将!ENV VAR_NAME解析为继承自字符串的自定义对象(既保留原始变量名,又能直接当作环境变量值使用);保存时通过YAML代表器将该自定义对象还原为!ENV VAR_NAME格式。

实现步骤

  1. 定义自定义EnvVar类
    继承自str,既让程序能直接当作字符串使用,又存储原始环境变量名用于保存时还原:
import os
import yaml

class EnvVar(str):
    def __new__(cls, var_name):
        # 从环境变量取值,创建str子类实例
        env_value = os.getenv(var_name, "")
        obj = super().__new__(cls, env_value)
        # 存储原始变量名
        obj.var_name = var_name
        return obj
  1. 注册YAML构造器(加载时解析!ENV标记)
    将YAML中的!ENV VAR_NAME节点解析为EnvVar实例:
def env_var_constructor(loader, node):
    # 提取!ENV后面的变量名字符串
    var_name = loader.construct_scalar(node)
    return EnvVar(var_name)

# 注册到SafeLoader
yaml.SafeLoader.add_constructor('!ENV', env_var_constructor)
  1. 注册YAML代表器(保存时还原!ENV标记)
    将EnvVar实例序列化为!ENV VAR_NAME格式:
def env_var_representer(dumper, data):
    # 用原始变量名生成!ENV标记的YAML节点
    return dumper.represent_scalar('!ENV', data.var_name)

# 注册到SafeDumper(用add_multi_representer处理子类)
yaml.SafeDumper.add_multi_representer(EnvVar, env_var_representer)
  1. 加载、修改、保存配置
# 加载配置
with open('config.yaml', 'r') as f:
    cfg = yaml.load(f, Loader=yaml.SafeLoader)

# 程序中直接使用环境变量值(和普通字符串无差异)
print(f"数据库密码:{cfg['db_password']}")

# 修改其他配置项
cfg['db_table'] = 'user_data'
cfg['app_hash'] = 'a1b2c3d4'

# 保存配置(自动保留!ENV标记)
with open('modified_config.yaml', 'w') as f:
    yaml.dump(cfg, f, Dumper=yaml.SafeDumper, default_flow_style=False)

效果验证

  • 加载时:cfg['db_password']是环境变量的实际值,可直接使用
  • 保存后:db_password字段仍为!ENV DB_PASSWORD,其他修改项正常保留

内容的提问来源于stack exchange,提问作者harleypig

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 23:31:04