英文:
Recursive function to read yaml files looking for a key which includes other yaml files
问题
我正在尝试编写一个函数,该函数读取一个 YAML 文件并查找特定的键。如果该键不存在,该函数应该检查是否存在 "_include" 键,然后检查该 YAML 文件,直到所有选项都尝试完毕或找到该键。
import yaml
import os.path
def load_yaml_data(yaml_path):
"""读取 YAML 文件并返回数据"""
try:
with open(yaml_path, 'r', encoding="utf-8") as yaml_file:
yaml_data = yaml.safe_load(yaml_file)
return yaml_data
except FileNotFoundError:
return None
except yaml.YAMLError as exc:
return None
def find_key_in_yaml_recursive(yaml_path, key):
print(f"打开 {yaml_path}")
yaml_data = load_yaml_data(yaml_path)
if yaml_data:
if key in yaml_data:
print(f"{key} 在 {yaml_path} 中找到")
return yaml_path
elif '_include' in yaml_data:
for include in yaml_data['_include']:
include_path = os.path.expandvars(include)
if not os.path.isabs(include_path):
include_path = os.path.abspath('/'.join([os.path.dirname(yaml_path), include_path]))
result = find_key_in_yaml_recursive(include_path, key)
if result:
return result
if __name__ == "__main__":
print(find_key_in_yaml_recursive("./test.yaml", "foo"))
目录结构:
.
| test.yaml
└─── test
│ │ test.yaml
│ └─── deeper
│ │ test.yaml
│ │ notexist.yaml
./test.yaml
---
_include:
- "test/test.yaml"
not_foo:
- "some data"
./test/test.yaml
---
_include:
- ./deeper/notexist.yaml
- ./deeper/test.yaml
foop:
- "somedata"
./test/deeper/notexist.yaml
---
nothinguseful:
- data
./test/deeper/test.yaml
---
foo:
- some data
somethingelse:
- data
'foo' 存在于 ./test/deeper/test.yaml 中。在大多数情况下,该函数将找到它并返回完整的 ./test/deeper/test.yaml 路径。但是,当 ./test/test.yaml 具有一个列出 deeper/notexist.yaml 在 deeper/test.yaml 之前的 "_include" 数组时,该函数返回 None。
我并没有进行太多的递归编程,但我知道你需要一个基本情况,但不确定如何在这种情况下实现基本情况。
英文:
I am attempting to write a function that reads a yaml file looking for a certain key. if the key does not exist, the function should check for an '_include' key and then check that yaml file for the same key until all options are exhausted or it finds the key.
import yaml
import os.path
def load_yaml_data(yaml_path):
"""Read a YAML file and return the data"""
try:
with open(yaml_path, 'r', encoding="utf-8") as yaml_file:
yaml_data = yaml.safe_load(yaml_file)
return yaml_data
except FileNotFoundError:
return None
except yaml.YAMLError as exc:
return None
def find_key_in_yaml_recursive(yaml_path, key):
print(f"opening {yaml_path}")
yaml_data = load_yaml_data(yaml_path)
# print(f"Yaml data : {yaml_data}")
if yaml_data:
if key in yaml_data:
print(f"{key} found in {yaml_path}")
return yaml_path
elif '_include' in yaml_data:
for include in yaml_data['_include']:
include_path = os.path.expandvars(include)
if not os.path.isabs(include_path):
include_path = os.path.abspath('/'.join([os.path.dirname(yaml_path), include_path]))
return find_key_in_yaml_recursive(include_path, key)
if __name__ == "__main__":
print(find_key_in_yaml_recursive("./test.yaml", "foo"))
Dir structure:
.
| test.yaml
└─── test
│ │ test.yaml
│ └─── deeper
│ │ test.yaml
│ │ notexist.yaml
./test.yaml
---
_include:
- "test/test.yaml"
not_foo:
- "some data"
./test/test.yaml
---
_include:
- ./deeper/notexist.yaml
- ./deeper/test.yaml
foop:
- "somedata"
./test/deeper/notexist.yaml
---
nothinguseful:
- data
./test/deeper/test.yaml
---
foo:
- some data
somethingelse:
- data
'foo' exists in ./test/deeper/test.yaml. In most circumstances, the function will find it and return the full ./test/deeper/test.yaml path. However, when ./test/test.yaml has an '_include' array that lists deeper/notexist.yaml before deeper/test.yaml the function returns None.
I have not done much recursive programming but i know you need a base case but i am unsure how to implement a base case in this scenario.
答案1
得分: 1
我认为这应该可以工作:
import yaml
import os.path
def load_yaml_data(yaml_path):
"""读取一个YAML文件并返回数据"""
try:
with open(yaml_path, 'r', encoding="utf-8") as yaml_file:
yaml_data = yaml.safe_load(yaml_file)
return yaml_data
except FileNotFoundError:
return None
except yaml.YAMLError as exc:
return None
def find_key_in_yaml_recursive(yaml_path, key):
print(f"打开 {yaml_path}")
yaml_data = load_yaml_data(yaml_path)
# print(f"Yaml数据 : {yaml_data}")
if yaml_data:
if key in yaml_data:
print(f"{key} 在 {yaml_path} 中找到")
return yaml_path
elif '_include' in yaml_data:
for include in yaml_data['_include']:
include_path = os.path.expandvars(include)
if not os.path.isabs(include_path):
include_path = os.path.abspath('/'.join([os.path.dirname(yaml_path), include_path]))
var = find_key_in_yaml_recursive(include_path, key)
if var:
return var
return None
if __name__ == "__main__":
print(find_key_in_yaml_recursive("./test.yaml", "foo"))
英文:
I think this should work:
import yaml
import os.path
def load_yaml_data(yaml_path):
"""Read a YAML file and return the data"""
try:
with open(yaml_path, 'r', encoding="utf-8") as yaml_file:
yaml_data = yaml.safe_load(yaml_file)
return yaml_data
except FileNotFoundError:
return None
except yaml.YAMLError as exc:
return None
def find_key_in_yaml_recursive(yaml_path, key):
print(f"opening {yaml_path}")
yaml_data = load_yaml_data(yaml_path)
#print(f"Yaml data : {yaml_data}")
if yaml_data:
if key in yaml_data:
print(f"{key} found in {yaml_path}")
return yaml_path
elif '_include' in yaml_data:
for include in yaml_data['_include']:
include_path = os.path.expandvars(include)
if not os.path.isabs(include_path):
include_path = os.path.abspath('/'.join([os.path.dirname(yaml_path), include_path]))
var = find_key_in_yaml_recursive(include_path, key)
if var:
return var
return None
if __name__ == "__main__":
print(find_key_in_yaml_recursive("./test.yaml", "foo"))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论