如何用Python在YAML文件中生成指定格式的延迟配置
问题:Python生成指定格式的YAML文件
我正在编写Python代码以根据需求生成YAML文件,现有实现代码如下:
import yaml script = {} room = 'kitchen' dev_num = '_2' script.update({'turn_off_all': { 'sequence':[ {'service': 'light.turn_off', 'entity_id': 'group.turn_off_wired_lights'}, {'delay': {'milliseconds': '>\n'+ "{{% if is_state('light.{}{}', 'off') %}}\n".format(room, dev_num) + ' 0\n'+ ' {% else %}\n'+ ' 500\n'+ ' {% endif %}\n' } } ]}}) with open("script.yaml", 'w', encoding='utf-8') as f: yaml.dump(script,f,allow_unicode=True,encoding='utf-8',sort_keys=False, width=float("inf"))
当前生成的script.yaml内容为:
turn_off_all: sequence: - service: light.turn_off entity_id: group.turn_off_wired_lights - delay: milliseconds: ">\n{% if is_state('light.kitchen_2', 'off') %}\n 0\n {% else %}\n 500\n {% endif %}\n"
但我期望的目标输出格式为:
turn_off_all: sequence: - service: light.turn_off entity_id: group.turn_off_wired_lights - delay: milliseconds: > {% if is_state('light.kitchen_2', 'off') %} 0 {% else %} 500 {% endif %}
我已尝试调整换行符、引号,以及设置default_style为'|'或'>',均未得到预期结果,请问如何实现该目标YAML格式?
解决方案
要生成带有**折叠块(>)**的目标YAML格式,原生PyYAML对这类精细格式的支持有限,推荐使用ruamel.yaml库来实现,它专门针对YAML格式细节做了优化。
步骤1:安装ruamel.yaml
pip install ruamel.yaml
步骤2:修改代码实现
from ruamel.yaml import YAML from ruamel.yaml.scalarstring import FoldedScalarString yaml = YAML() # 设置缩进规则,匹配目标格式的缩进风格 yaml.indent(mapping=2, sequence=4, offset=2) yaml.preserve_quotes = False script = {} room = 'kitchen' dev_num = '_2' # 构造延迟逻辑的字符串,注意内部缩进要符合目标格式 delay_content = f"""{% if is_state('light.{room}{dev_num}', 'off') %} 0 {% else %} 500 {% endif %}""" script['turn_off_all'] = { 'sequence': [ {'service': 'light.turn_off', 'entity_id': 'group.turn_off_wired_lights'}, # 用FoldedScalarString标记该字符串为折叠块类型 {'delay': {'milliseconds': FoldedScalarString(delay_content)}} ] } with open("script.yaml", 'w', encoding='utf-8') as f: yaml.dump(script, f)
关键说明
FoldedScalarString是ruamel.yaml提供的类型,专门用来生成YAML中的折叠块(>开头的格式),能自动处理换行和缩进。- 通过
yaml.indent()可以精准控制映射、序列的缩进量,确保生成的YAML和目标格式完全一致。 - 直接构造带正确内部缩进的字符串内容,无需手动添加
>符号,FoldedScalarString会自动处理。
最终生成结果
运行代码后,生成的script.yaml将完全符合你的期望:
turn_off_all: sequence: - service: light.turn_off entity_id: group.turn_off_wired_lights - delay: milliseconds: > {% if is_state('light.kitchen_2', 'off') %} 0 {% else %} 500 {% endif %}
如果坚持使用原生PyYAML,需要自定义代表折叠块的类并注册对应的representer,实现逻辑繁琐且容易出错,因此优先推荐ruamel.yaml方案。
内容的提问来源于stack exchange,提问作者Unknown _
相关产品推荐
相关产品推荐

