Python3生成适配Ansible Jinja的无引号含双大括号YAML内容
Python3生成适配Ansible Jinja的无引号含双大括号YAML内容
我太懂你这个困扰了——用PyYAML输出带Jinja模板标记的YAML时,那些{{ val }}总是被自动套上单引号,放到Ansible里用起来特别别扭。别担心,咱们来解决这个问题!
问题的根源在于PyYAML的默认行为:当它检测到字符串里包含大括号这类YAML语法里的特殊字符时,会自动给字符串加上引号,避免解析时出现歧义。但我们需要的是让它把{{ val }}当成普通的纯文本输出,不需要额外的引号。
解决方案:用PlainScalarString指定无引号纯量
PyYAML提供了PlainScalarString类,专门用来生成无引号的纯量字符串。我们只需要把目标字符串用这个类包裹起来,就能让dump输出时不带引号。
代码示例:
import yaml from yaml.scalarstring import PlainScalarString data = { 'user': PlainScalarString('{{ val }}') } # 输出单行无缩进的格式,同时保持键的原始顺序 print(yaml.dump(data, default_flow_style=False, sort_keys=False))
运行这段代码后,你会得到完全符合需求的输出:
user: {{ val }}
参数说明
PlainScalarString('{{ val }}'):明确告诉PyYAML,这个字符串是不需要加引号的纯文本纯量sort_keys=False:阻止PyYAML自动对字典的键进行排序,保证输出的键顺序和你定义的一致default_flow_style=False:生成块样式的YAML,正好对应你要的单行键值对格式(如果设为True会生成流式格式{user: {{ val }}},不符合你的需求)
另一种思路:自定义字符串代表器
如果你有大量这类带Jinja标记的字符串需要处理,也可以给str类型自定义一个代表器,让PyYAML自动识别包含{{的字符串并以无引号形式输出:
import yaml from yaml.scalarstring import PlainScalarString def str_presenter(dumper, data): if '{{' in data: return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='') return dumper.represent_scalar('tag:yaml.org,2002:str', data) yaml.add_representer(str, str_presenter) data = { 'user': '{{ val }}', 'normal_str': 'hello world' } print(yaml.dump(data, sort_keys=False, default_flow_style=False))
这个方法会自动处理所有包含{{的字符串,普通字符串则保持原来的输出逻辑,适合批量处理的场景。
备注:内容来源于stack exchange,提问作者Maxim
相关产品推荐
相关产品推荐

