使用python访问yaml中的元素
Posted
技术标签:
【中文标题】使用python访问yaml中的元素【英文标题】:Access elements inside yaml using python 【发布时间】:2020-12-24 22:40:08 【问题描述】:我正在使用 yaml 和 pyyaml 来配置我的应用程序。
可以这样配置吗-
config.yml -
root:
repo_root: /home/raghhuveer/code/data_science/papers/cv/AlexNet_lght
data_root: $root.repo_root/data
service:
root: $root.data_root/csv/xyz.csv
yaml加载功能-
def load_config(config_path):
config_path = os.path.abspath(config_path)
if not os.path.isfile(config_path):
raise FileNotFoundError(" does not exist".format(config_path))
else:
with open(config_path) as f:
config = yaml.load(f, Loader=yaml.SafeLoader)
# logging.info(config)
logging.info("Config used for run - \n".format(yaml.dump(config, sort_keys=False)))
return DotDict(config)
电流输出-
root:
repo_root: /home/raghhuveer/code/data_science/papers/cv/AlexNet_lght
data_root: $root.repo_root/data
service:
root: $root.data_root/csv/xyz.csv
所需的输出 -
root:
repo_root: /home/raghhuveer/code/data_science/papers/cv/AlexNet_lght
data_root: /home/raghhuveer/code/data_science/papers/cv/AlexNet_lght/data
service:
root: /home/raghhuveer/code/data_science/papers/cv/AlexNet_lght/data/csv/xyz.csv
这甚至可以用 python 实现吗?如果是这样,任何帮助都会非常好。
提前致谢。
【问题讨论】:
这能回答你的问题吗***.com/questions/1773805/… 不错的任务。我看不出为什么这是不可能的。你自己尝试过什么吗?真实的结构是什么样的(结构有多“深”)?变量总是“***”键吗?请提供更具体的信息,以便更轻松地回答 一些帮助您入门的想法:您可以使用 template strings 并自己构建变量字符串,或者您可以使用正则表达式。 @Wups 我是一个 yaml 配置的初学者,你的评论让我无法理解。你能帮我把它变笨吗? @JanStránský 我已经编辑了问题以显示我当前的方法。这是我想要保留 yaml 的深度 【参考方案1】:一般方法:
按原样读取文件 搜索包含$
的字符串:
确定“变量”的“路径”
用实际值替换“变量”
一个例子,使用递归调用字典并替换字符串:
import re, pprint, yaml
def convert(input,top=None):
"""Replaces $key1.key2 with actual values. Modifies input in-place"""
if top is None:
top = input # top should be the original input
if isinstance(input,dict):
ret = k:convert(v,top) for k,v in input.items() # recursively convert items
if input != ret: # in case order matters, do it one or several times more until no change happens
ret = convert(ret)
input.update(ret) # update original input
return input # return updated input (for the case of recursion)
if isinstance(input,str):
vars = re.findall(r"\$[\w_\.]+",input) # find $key_1.key_2.keyN sequences
for var in vars:
keys = var[1:].split(".") # remove dollar and split by dots to make "key chain"
val = top # starting from top ...
for k in keys: # ... for each key in the key chain ...
val = val[k] # ... go one level down
input = input.replace(var,val) # replace $key sequence eith actual value
return input # return modified input
# TODO int, float, list, ...
with open("in.yml") as f: config = yaml.load(f) # load as is
convert(config) # convert it (in-place)
pprint.pprint(config)
输出:
'root': 'data_root': '/home/raghhuveer/code/data_science/papers/cv/AlexNet_lght/data',
'repo_root': '/home/raghhuveer/code/data_science/papers/cv/AlexNet_lght',
'service': 'root': '/home/raghhuveer/code/data_science/papers/cv/AlexNet_lght/data/csv/xyz.csv'
注意:YAML 在这里并不重要,它也适用于 JSON、XML 或其他格式。
注意2:如果您只使用 YAML 和专门使用 python,this post 的一些答案可能有用(使用锚点和引用以及特定于应用程序的本地标签)
【讨论】:
以上是关于使用python访问yaml中的元素的主要内容,如果未能解决你的问题,请参考以下文章