我有以下两个单独的YAML文件。
val.yaml
:在此处定义变量expr.yaml
:此处定义表达式 val.yaml
x: 2
y: 3
z: 5
expr.yaml
result: (x + y) * z
parse.py
import yaml
with open('val.yaml', 'r') as stream:
val = yaml.load(stream)
with open('expr.yaml', 'r') as stream:
expr = yaml.load(stream)
....
# this should be (2 + 3) * 5 = 25
print expr['result']
如何通过引用expr.yaml
中定义的变量来评估val.yaml
中定义的表达式?
答案 0 :(得分:2)
使用sympy
最容易做到这一点:
from __future__ import print_function
import ruamel.yaml
from sympy.parsing.sympy_parser import parse_expr
yaml = ruamel.yaml.YAML(typ='safe')
with open('var.yaml') as stream:
vars = yaml.load(stream)
with open('expr.yaml') as stream:
expr = yaml.load(stream)
for k in expr:
l = parse_expr(expr[k], vars)
print('{}: {}'.format(k, l))
打印(使用Python 2或3):
result: 25
print
作为函数,因此应该导入from __future__
。计划使用print语句的Python 2.7的使用期限为两年,因此请使用此类前向兼容性导入并习惯于使用它们。yaml.load()
,因为它可能是不安全的,当然,如果其他人正在编辑您的输入文件。使用yaml.safe_load()
或使用上面的命令(加载速度也更快)。答案 1 :(得分:0)
这是一种实现方法,即使我在生产环境中强烈不鼓励使用此方法(应避免使用eval
,也应清除输入等)。这个想法是在表达式yaml(在result
中遵循相同的命名约定的假设下,执行s替换,迭代yaml中的变量。这里是一个示例:
#!/usr/bin/env python
import yaml
VARS_YAML = """
x: 2
y: 3
z: 5
"""
EXPR_YAML = """
result: (x + y) * z
"""
vars = yaml.load(VARS_YAML)
expr = yaml.load(EXPR_YAML)
for key, value in vars.items(): # for python2: vars.iteritems()
expr['result'] = expr['result'].replace(key, str(value))
r = eval(expr['result'])
print(r) # for python2: print r
# => 25
此代码适用于python-3(目前我唯一可用的版本),但是将其移至python-2(我认为是您的版本)很简单。如果您希望从文件中加载Yaml:
with open('var.yaml', 'r') as var_file:
vars = yaml.load(var_file)
绰绰有余。