
本文介绍如何在 Python3 中通过自定义 YAML Dumper,使包含 {{ val }} 这类 Ansible/Jinja 模板语法的字符串在序列化时不被自动加上单引号,确保生成符合 Ansible 要求的干净、单行、无引号 YAML。
本文介绍如何在 python3 中通过自定义 yaml dumper,使包含 `{{ val }}` 这类 ansible/jinja 模板语法的字符串在序列化时不被自动加上单引号,确保生成符合 ansible 要求的干净、单行、无引号 yaml。
默认情况下,PyYAML 为保证 YAML 解析安全性,会对包含特殊字符(如空格、{、}、-、: 等)的字符串自动添加单引号。这虽然符合 YAML 规范,但在与 Ansible 集成时会导致 Jinja2 模板变量(如 {{ val }})被当作普通字符串字面量处理,无法被 Ansible 正确解析执行。
解决方法是继承 yaml.Dumper 并重写 choose_scalar_style() 方法——该方法决定标量值的输出风格(如 '' 表示“原样输出”,' 表示单引号," 表示双引号,| 表示块样式等)。将其强制返回空字符串 '',即可让所有字符串(包括含双花括号的值)以无引号、非转义形式输出。
以下是完整可运行示例:
import yaml
class PlainDumper(yaml.Dumper):
def choose_scalar_style(self):
return ''
data = {
'user': '{{ val }}',
'role': 'admin',
'template': '{{ lookup("env", "HOME") }}'
}
# 关键参数:Dumper=PlainDumper,并禁用默认换行和缩进以满足单行要求
result = yaml.dump(
data,
Dumper=PlainDumper,
default_flow_style=True, # 强制内联格式(如 {user: {{ val }}, role: admin})
allow_unicode=True,
width=1024 # 防止长值被折行
)
print(result.strip())
输出为(单行、无引号、符合 Ansible 解析预期):
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
{user: {{ val }}, role: admin, template: {{ lookup("env", "HOME") }}}
⚠️ 注意事项:
-
PlainDumper会全局禁用引号保护,因此仅适用于你完全信任输入数据、且目标场景(如 Ansible playbook vars)明确支持无引号模板语法的场合; - 若字典中混有需引号的值(如含换行或冒号的字符串),应改用更精细的控制方式(例如为特定键定制
Representer); -
default_flow_style=True是实现单行输出的关键,否则即使无引号仍可能生成多行块格式; - 不建议在生产通用配置生成器中全局启用此 Dumper,推荐按需实例化或封装为专用函数。
总结:通过轻量级 Dumper 自定义,我们绕过了 PyYAML 的保守转义策略,在保持代码简洁的同时,精准满足 Ansible 对 Jinja2 模板变量的 YAML 表达需求。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










