如何创建动态YAML字符串

时间:2016-11-08 07:06:12

标签: python yaml

我有一个YAML文件

tests:
  - is-gt: val, 2
    info: "Test Succeeded!!, val is greater than 2, it is <{{post['val']}}>"
    err: "Test Failed!!, val is not greater than 2, it is <{{post['val']}}>"
在这种情况下,代替val的硬编码值(即2),它应该直接采用操作“is-gt”指定的值。 如果我将测试操作更改为“is-gt:val,3”,它应该自动将此值包含在信息和错误消息中。

我该怎么做?我在一些Python脚本中进一步使用这个YAML文件来读取它。

2 个答案:

答案 0 :(得分:1)

你的is-gt只是YAML的标量字符串,它充当映射的键。该字符串没有什么特别之处,它肯定不是&#34;操作&#34;。

您可以对加载的YAML进行后期处理(例如,如果您使用ruamel.yaml / PyYAML中的safe_load)。什么是更清晰的YAML,是您标记序列项,并根据该标记将映射键/值加载到解释is-gt的特定对象中,并更新成为其属性的其他值的标量字符串。

这样的对象最好具有类似地图的界面,您必须决定在加载时进行解析,或者在通过其键检索值时使用延迟评估。

答案 1 :(得分:1)

YAML是一种数据序列化语言,而不是数据处理语言。模板功能超出了它的范围(虽然在这个方向上存在一些可选功能,但这里不适用)。

已经提出了使用其他模板语言的后处理。我想添加使用pystache的建议,因为它是一种可能比使用Jinja更合适的最小语言。

此外,我建议将价值规格放入地图中。由于你已经在字符串中使用{{来表示其他内容,我建议告诉pystache使用另一种转义方法。例如:

tests:
  - is-gt: {val: 2}
    info: "Test Succeeded!!, val is greater than `val`, it is <{{post['val']}}>"
    err: "Test Failed!!, val is not greater than `val`, it is <{{post['val']}}>"

您现在可以像这样解析它:

import yaml, pystache

raw = yaml.safe_load("""
tests:
  - is-gt: {val: 2}
    info: "Test Succeeded!!, val is greater than `val`, it is <{{post['val']}}>"
    err: "Test Failed!!, val is not greater than `val`, it is <{{post['val']}}>"
""")

def dynString(inputs, template):
    return pystache.render("{{=` `=}}" + template, inputs)

tests = []
for rawtest in raw["tests"]:
    test = {}
    inputs = rawtest["is-gt"]
    for msg in ["info", "err"]:
        test[msg] = dynString(inputs, rawtest[msg])
    tests.append(test)

print(tests)

哪个输出:

[{'info': "Test Succeeded!!, val is greater than 2, it is <{{post['val']}}>",
  'err': "Test Failed!!, val is not greater than 2, it is <{{post['val']}}>"}]