JSON 个模板在 python 中?

JSON templates in python?

我希望能够在 json / yaml 中指定一个模板并根据上下文填写值:

root:
  child: {{child_value}}
  other_child: 1

然后在我的代码中我可以 运行:

output = format("template.yaml", context=dict(child_value=1))

通常模板系统并不能很好地工作,因为它们对两个字符串进行编码。理想情况下,你会想要一些 aware 的 yaml 结构(这似乎是 docker-compose 内部使用的方法,例如。我遇到过具有这种心态的图书馆xml 之前)

我可以这样做吗 - 最好使用标准的东西?

研究

基本上有以下三种方法:

使用模板引擎处理输入然后将其提供给 YAML 解析器

这是您的任何事情方法:您可以使用任何您想要的模板引擎,从标准的format到小胡子等最小的东西到功能齐全的解决方案像金贾。正如您所说,这样做的缺点是引擎不知道 YAML 结构。这需要在粘贴复杂值(必须进行 YAML 序列化)和多行字符串(必须正确缩进)时手动调整。

这种方法用于例如 Ansible、SaltStack(Jinja)和 Helm(Go 的 text/template)。

使用模板引擎处理输入,然后将其提供给 YAML 解析器

这通常意味着您使用故障安全模式解析 YAML,仅生成列表、字典和字符串。然后,您使用模板引擎或某种其他类型的处理器处理每个字符串,例如,它们可以引用 YAML 数据的其他部分。

这种方法的问题是您需要通过 YAML 解析器获取模板的语法作为内容。因此,不建议使用像 {{child_value}} 这样的语法,因为 YAML 处理器会将其读取为两个嵌套映射。

另一个问题是不清楚何时以及如何检查输入数据的有效性:你不能在解析 YAML 时这样做,因为那里会有未处理的模板表达式,但如果您的模板解决方案允许引用结构中的其他值,这些值尚未进行类型检查。

这种方法用于例如 Azure Pipelines,它使用语法 ${{...}}}$[...]

使用 YAML 标签作为模板引擎

您可以注册自定义构造函数以允许类似

root:
  child: !var child_value
  other_child: 1

标签 !var 的自定义构造函数然后将获取名为 child_value 的值。这样做的好处是您不需要额外的模板引擎,并且您的文件只需要遵循一种语法。但是它很健谈,我很少看到它的实际应用。

与以前的方法相比,我真的没有看到任何缺点(尽管它与引用有同样的问题),我只能假设这是异国情调的,因为很多人并不真正了解 YAML 标签.

结论

第一种方法在某些地方放置标量 (string/numeric/etc) 值更简单。其他方法更适合注入复杂值,因为您可以将它们作为 Python 值注入,而不是为它们生成 YAML 子结构。没有完美的解决方案,这取决于您的用例。