Как я могу оценить алгебраические выражения, определенные в YAML? - PullRequest
0 голосов
/ 05 июля 2018

У меня есть два следующих отдельных файла 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?

Ответы [ 2 ]

0 голосов
/ 05 июля 2018

Это проще всего сделать с помощью 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 как функцию, даже если вы застряли в Python 2.7, следовательно, from __future__ import. Планируется, что Python 2.7 с его оператором печати будет завершен через два года, поэтому используйте такие импорты прямой совместимости и привыкните к их использованию.
  • вы не должны использовать PyYAML yaml.load(), так как это может быть небезопасно, конечно, если кто-то еще редактирует ваши входные файлы. Либо используйте yaml.safe_load(), либо используйте вышеперечисленное (что также загружается быстрее).
0 голосов
/ 05 июля 2018

Это способ сделать это, даже если я категорически не одобряю этот подход в производственной ситуации (следует избегать eval, ввод данных должен быть продезинфицирован и т. Д.). Идея состоит в том, чтобы выполнить подстановку s, перебирая переменные в yaml, в предположении, что выражение yaml (в result) следует тому же соглашению об именах. Вот образец:

#!/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)

более чем достаточно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...