San*_*och 6 python jinja2 pyyaml computed-properties
我有一个YAML文件(all.yaml),如下所示:
...
var1: val1
var2: val2
var3: {{var1}}-{{var2}}.txt
...
Run Code Online (Sandbox Code Playgroud)
如果我像这样在Python中加载它:
import yaml
f = open('all.yaml')
dataMap = yaml.safe_load(f)
f.close()
print(dataMap["var3"])
Run Code Online (Sandbox Code Playgroud)
输出{{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 )
Run Code Online (Sandbox Code Playgroud)
不再抛出异常,现在我陷入困境,必须研究如何继续.
小智 7
首先定义一个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)
Run Code Online (Sandbox Code Playgroud)
运行:
$ ./test.py
var1: val1
var2: val2
var3: val1-val2.txt
Run Code Online (Sandbox Code Playgroud)
YAML 规范中没有标量部分的替换/替换。
您想要在该级别上执行的任何操作都必须在您的应用程序中完成。对于我和 YAML 来说,{{var1}}这只是一个嵌套映射。{{var1}}是 的缩写{{var1: null}: null}。之后就-不允许了。
但是您的帖子存在多个问题:
您使用的 PyYAML 仅支持旧版 (2005) YAML 1.1。因此,如果不像 YAML 1.2 中那样...使用显式文档开始 ( ) ,就不能拥有多个文档(即以 结尾)---
即使您更正要读取的第一行,---文件...也不会加载,因为字典后面{{var1}}不能跟标量-(来自-{{var2}}.txt)
如果您只是{{var1}}在文件中使用,PyYAML 无法加载它,因为它将 YAML 映射加载为 Python 字典,而 Python 不允许字典使用可变键。就像你TypeError在 Python 中尝试执行以下操作时得到的结果一样:{dict(var1=None): None}
所以你至少应该将输入文件更改all.yaml为:
---
var1: val1
var2: val2
var3: '{{var1}}-{{var2}}.txt'
...
Run Code Online (Sandbox Code Playgroud)
使其加载到 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"])
Run Code Online (Sandbox Code Playgroud)
将打印您想要的内容:
val1-val2.txt
Run Code Online (Sandbox Code Playgroud)