Мне нужно использовать переменную среды "PATH" в файле yaml, которая должна обрабатываться скриптом.
Это переменная среды, которую я установил на моем терминале:
$ echo $PATH
/Users/abc/Downloads/tbwork
Это мой пример.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']
Может ли кто-нибудь помочь мне понять правильный способ сделать это, если я делаю это неправильно?
Библиотека 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
load()
(прочитайте документацию, если вы не знаете почему), когда это не нужно (почти всегда). Всегда используйте safe_load()
в примерах.
safe_load()
мне пришлось изменить вышеописанное, например, так ... yaml.add_implicit_resolver('!path', path_matcher, None, SafeLoader)
yaml.add_constructor('!path', path_constructor, SafeLoader)
os.environ
.