Как заменить значение переменной окружения в файле yaml для анализа с помощью скрипта Python - PullRequest
0 голосов
/ 19 сентября 2018

Мне нужно использовать переменную окружения "PATH" в файле yaml, которую нужно проанализировать с помощью скрипта.

Это переменная окружения, которую я установил на своем терминале:

$ echo $PATH
/Users/abc/Downloads/tbwork

Это мой sample.yml:

---
Top: ${PATH}/my.txt
Vars:
- a
- b

Когда я анализирую этот файл yaml смой сценарий, я не вижу PATH фактическое значение переменных.

Это мой сценарий:

import yaml
import os
import sys

stream = open("sample.yml", "r")
docs = yaml.load_all(stream)
for doc in docs:
    for k,v in doc.items():
        print k, "->", v
    print "\n",

Вывод:

Top -> ${PATH}/my.txt
Vars -> ['a', 'b']

Ожидаемый вывод:

Top -> /Users/abc/Downloads/tbwork/my.txt
Vars -> ['a', 'b']

Может кто-нибудь помочь мне разобратьсяправильный способ сделать это, если я делаю это неправильно?

Ответы [ 2 ]

0 голосов
/ 22 марта 2019

Вот альтернативная версия, которая использует новый класс Loader, если вы не хотите изменять глобальный / стандартный загрузчик yaml.

И что более важно, он правильно заменяет интерполированные строки, которые не являются просто средойпеременные, например path/to/${SOME_VAR}/and/${NEXT_VAR}/foo/bar

        path_matcher = re.compile(r'.*\$\{([^}^{]+)\}.*')
        def path_constructor(loader, node):
            return os.path.expandvars(node.value)

        class EnvVarLoader(yaml.SafeLoader):
            pass

        EnvVarLoader.add_implicit_resolver('!path', path_matcher, None)
        EnvVarLoader.add_constructor('!path', path_constructor)

        with open(configPath) as f:
            c = yaml.load(f, Loader=EnvVarLoader)
0 голосов
/ 19 сентября 2018

Библиотека PY-yaml не разрешает переменные окружения по умолчанию.Вам необходимо определить неявный распознаватель, который найдет регулярное выражение, определяющее переменную среды, и выполнит функцию для ее разрешения.

Вы можете сделать это через yaml.add_implicit_resolver и yaml.add_constructor.В приведенном ниже коде вы определяете распознаватель, который будет соответствовать переменной $ {env} в значении YAML, и вызываете функцию path_constructor для поиска переменной среды.

import yaml
import re
import os

path_matcher = re.compile(r'\$\{([^}^{]+)\}')
def path_constructor(loader, node):
  ''' Extract the matched value, expand env variable, and replace the match '''
  value = node.value
  match = path_matcher.match(value)
  env_var = match.group()[2:-1]
  return os.environ.get(env_var) + value[match.end():]

yaml.add_implicit_resolver('!path', path_matcher)
yaml.add_constructor('!path', path_constructor)

data = """
env: ${VAR}/file.txt
other: file.txt
"""

if __name__ == '__main__':
  p = yaml.safe_load(data)
  print(os.environ.get('VAR')) ## /home/abc
  print(p['env']) ## /home/abc/file.txt
...