Распарсить yaml файл в таблицу
На вход подается yaml
файл:
apiVersion: apps/v1
kind: Deployment
metadata:
name: example
namespace: Main
spec:
selector:
matchLabels:
app: httpd
replicas: 3
template:
metadata:
labels:
app: httpd
spec:
containers:
- name: httpd
image: >-
image-registry.openshift-image-registry.svc:5000/openshift/httpd:latest
ports:
- containerPort: 8080
Нужно его превратить в таблицу, где первый столбец это ключ, а второй значение, причем ключ должен быть сохранен вместе с вложенностью.
Для начала я загружаю yaml
файл:
import yaml
from yaml.loader import FullLoader
yaml_file_path = 'example/deployment.yaml'
with open(yaml_file_path) as file:
data = yaml.load(file, Loader=FullLoader)
print(data)
На монитор выводит файл полностью.
Теперь я хочу пройти весь файл и обработать каждый ключ, делаю рекурсивный метод:
def GetData(data):
for item in data:
print(item)
GetData(item)
with open(yaml_file_path) as file:
data = yaml.load(file, Loader=FullLoader)
GetData(data)
Он уходит в бесконечную рекурсию и падает с ошибкой.
Помогите с решением, пожалуйста.
Ответы (1 шт):
Ну вот вам пример рекурсивного обхода. У вас там кроме словарей есть ещё списки. Они хоть из одного элемента, но где гарантия, что не будет списков из нескольких элементов? Поэтому элементы списков я пронумеровал с нуля.
def GetData(data, prefix):
if isinstance(data, dict):
for k, v in data.items():
yield from GetData(v, f'{prefix}/{k}')
elif isinstance(data, list):
for i, v in enumerate(data):
yield from GetData(v, f'{prefix}/{i}')
else:
yield (prefix, data)
with open(yaml_file_path) as file:
data = yaml.load(file, Loader=FullLoader)
for item in GetData(data, ''):
print(item)
На выходе кортежи, сами их приводите в какой нужно вид:
('/apiVersion', 'apps/v1')
('/kind', 'Deployment')
('/metadata/name', 'example')
('/metadata/namespace', 'Main')
('/spec/selector/matchLabels/app', 'httpd')
('/spec/replicas', 3)
('/spec/template/metadata/labels/app', 'httpd')
('/spec/template/spec/containers/0/name', 'httpd')
('/spec/template/spec/containers/0/image', 'image-registry.openshift-image-registry.svc:5000/openshift/httpd:latest')
('/spec/template/spec/containers/0/ports/0/containerPort', 8080)
P.S. А ваш код зацикливается, потому что он сначала перебирает ключи корневого словаря, потом сами эти ключи перебирает как коллекции - по одному символу, а потом каждый такой символ перебирает как коллекцию, ну и всё, дальше этот символ повторяется до бесконечности, потому что как коллекция он перебирается снова как этот же символ.
['apiVersion', 'kind', ...] -> ['a', 'p', 'i', ...] -> ['a'] -> ['a'] -> ...