【问题标题】:Leverage Python f-strings with Yaml files?将 Python f 字符串与 Yaml 文件结合使用?
【发布时间】:2019-04-01 22:16:14
【问题描述】:

如果我有一个 yaml 文件,其中包含一个与 python f-strings 合作使用的带有括号符号 {} 的字符串,那么在这里如何利用 f-string 插值?以这个简单的 yaml 文件为例:

# tmp.yaml
k1: val1
k2: val2 as well as {x}

如果x = 'val3',我希望k2的值反映val2 as well as val3

# app.py
x = 'val3'
with open('tmp.yaml', 'rt') as f:
    conf = yaml.safe_load(f)

print(conf)
{'k1': 'val1', 'k2': 'val2 as well as {x}'}

这可以很容易地用格式字符串来完成...

print(conf['k2'].format(x=x))
val2 as well as val3

但是如何对 f-strings 做同样的事情呢?

【问题讨论】:

标签: python yaml python-3.6 f-string


【解决方案1】:

您可以定义自定义构造函数:

import yaml

values = { 'x': 'val3' }

def format_constructor(loader, node):
  return loader.construct_scalar(node).format(**values)

yaml.SafeLoader.add_constructor(u'!format', format_constructor)

conf = yaml.safe_load("""
k1: val1
k2: !format val2 as well as {x}
""")

print(conf)

如果您不想使用标签!format,也可以使用add_constructoru'tag:yaml.org,2002:str' 作为标签。这将用你的覆盖默认的字符串构造函数。

【讨论】:

  • 您能提供一些这方面的背景吗?
  • @user9074332 发生的情况是您将本地标记 !format 放在 YAML 标量 val2 as well as {x} 上,然后告诉 PyYAML „当您遇到标记为 !format 的节点时,使用此函数来从中构造目标值“。在函数中,您首先使用 PyYAML 的常用构造函数构造一个字符串,然后在其上调用 format,给出包含您要执行的替换的 value dict。您也可以只使用...format(x='val3'),但我展示的方法可以推广到具有多个替换模板的更大 YAML 文件。
【解决方案2】:

我发现jinja2 为这个问题提供了最简单的解决方案。

源码yaml文件:

# tmp.yaml
k1: val1
k2: val2 as well as {{ x }}

读取文件并使用 jinja 模板进行渲染:

with open('tmp.yaml', 'rt') as f:
    conf = f.read().rstrip()

print(conf)
# 'k1: val1\nk2: val2 as well as {{ x }}'

import jinja2
template = Template(conf)
conf = template.render(x='val3')
config = yaml.safe_load(conf)

print(config)
# {'k1': 'val1', 'k2': 'val2 as well as val3'}

【讨论】:

    猜你喜欢
    • 2016-09-05
    • 1970-01-01
    • 2020-02-06
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    • 2018-07-11
    • 2019-01-08
    • 1970-01-01
    相关资源
    最近更新 更多