我有一个YAML文件(all.yaml
),如下所示:
...
var1: val1
var2: val2
var3: {{var1}}-{{var2}}.txt
...
如果我在Python中加载它:
import yaml
f = open('all.yaml')
dataMap = yaml.safe_load(f)
f.close()
print(dataMap["var3"])
输出为{{var1}}-{{var2}}.txt
而不是val1-val2.txt
。
是否可以用值替换嵌套变量?
我尝试加载它:
import jinja2
templateLoader = jinja2.FileSystemLoader( searchpath="/path/to/dir" )
templateEnv = jinja2.Environment( loader=templateLoader )
TEMPLATE_FILE = "all.yaml"
template = templateEnv.get_template( TEMPLATE_FILE )
不再抛出异常,现在我陷入困境,必须研究如何继续。
答案 0 :(得分:0)
我不相信你可以使用:
yaml.load
或
yaml.safe_load
在包含jinja2
个变量作为值的文件上。 {{variable}}
将尝试被yaml解释为dict。
答案 1 :(得分:-1)
以下是一种可能的解决方案:
expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token
模块例如:
yaml
这适用于您的特定示例,但是对于嵌套数据结构不会做任何有用的事情(事实上,它可能会爆炸)。
答案 2 :(得分:-1)
首先定义一个Undefined
类并加载yaml以获取已知值。然后再次加载并使用已知值进行渲染。
#!/usr/bin/env python
import yaml
from jinja2 import Template, Undefined
str1 = '''var1: val1
var2: val2
var3: {{var1}}-{{var2}}.txt
'''
class NullUndefined(Undefined):
def __getattr__(self, key):
return ''
t = Template(str1, undefined=NullUndefined)
c = yaml.safe_load(t.render())
print t.render(c)
运行它:
$ ./test.py
var1: val1
var2: val2
var3: val1-val2.txt
答案 3 :(得分:-2)
YAML规范中没有替换/替换标量部分。
您要在该级别上执行的任何操作都必须在您的应用程序中完成。对我来说,对于YAML,{{var1}}
只是一个嵌套映射。 {{var1}}
是{{var1: null}: null}
的缩写。之后,-
不被允许。
但是您的帖子存在多个问题:
您正在使用仅支持旧版(2005)YAML 1.1的PyYAML。因此,如果不使用明确的文档开头(...
),您就不能拥有多个文档(即以---
结尾),就像在YAML 1.2中一样
即使您更正了第一行来阅读---
而不是...
,您的文件也无法加载,因为标题{{var1}}
无法跟随标量-
}(来自-{{var2}}.txt
)
如果您只在文件中使用{{var1}}
,PyYAML无法加载,因为它加载YAML映射作为Python dict并且Python不允许dict的可变键。就像在尝试执行此操作时在Python中获得TypeError
一样:{dict(var1=None): None}
因此,您至少应将输入文件all.yaml
更改为:
---
var1: val1
var2: val2
var3: '{{var1}}-{{var2}}.txt'
...
将此内容加载到YAML中。
您必须加载此文件两次:
渲染模板后,在PyYAML中再次加载(字符串)并获得所需的值。
鉴于上面在当前目录和此程序中指定的更正all.yaml
:
import yaml
import jinja2
YAML_FILE = 'all.yaml'
with open(YAML_FILE) as fp:
dataMap = yaml.safe_load(fp)
env = jinja2.Environment(loader=jinja2.FileSystemLoader(searchpath='.'))
template = env.get_template(YAML_FILE)
data = yaml.safe_load(template.render(**dataMap))
print(data["var3"])
将打印您想要的内容:
val1-val2.txt