利用 Yaml 文件的 Python f 字符串?
Leverage Python f-strings with Yaml files?
如果我有一个包含括号符号 {} 的字符串的 yaml 文件与 python f 字符串一起使用,那么在这里如何利用 f 字符串插值?以这个简单的 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 弦做同样的事情?
您可以定义自定义构造函数:
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_constructor
和 u'tag:yaml.org,2002:str'
作为标签。这将用您的构造函数覆盖默认的字符串构造函数。
我发现 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'}
如果我有一个包含括号符号 {} 的字符串的 yaml 文件与 python f 字符串一起使用,那么在这里如何利用 f 字符串插值?以这个简单的 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 弦做同样的事情?
您可以定义自定义构造函数:
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_constructor
和 u'tag:yaml.org,2002:str'
作为标签。这将用您的构造函数覆盖默认的字符串构造函数。
我发现 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'}