LINUX.ORG.RU

Логика получения вложенных объектов при неизвестной степени вложенности

 , ,


0

1

Есть первоначальный конфиг, который помимо прочего может содержать указания на другие конфиги в формате «КОНФИГИ=конфиг1 конфиг2 … конфигN». Каждый из этих конфигов может помимо прочего также содержать указания на другие конфиги, при этом они НЕ пересекаются с множеством конфигов верхнего уровня. Вопрос: как на баше или питоне задать логику получения ВСЕХ вложенных конфигов, при этом сохранить их иерархию (конфиг нижнего уровня должен стоять ПОСЛЕ конфига верхнего, который на него указывал). Готовый код не нужен, мне просто надо понять логику. Какой-то простой цикл тут явно не заходит из-за неизвестной степени вложенности (она точно не бесконечная). Специалисты по алгоритмам, подскажите, что почитать, куда покапать. Спасибо.

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

Spoofing ★★★★★
()

Какой-то простой цикл тут явно не заходит из-за неизвестной степени вложенности

Поиск в глубину - азбука работы с деревьями

goingUp ★★★★★
()

Обход директорий с поддиректориями делал? Либо рекурсия, либо обход через стек (если там может быть очень много вложенности), либо просто буффер со списками.

Без структуры конфига не совсем понятно то, как лучше сделать.

Если у тебя плоский конфиг, то сработает что-то вроде (это обход графа в ширину):

config = {}
paths = [initial_config]
while len(paths) > 0:
  path = paths[0]
  paths = paths[1:]

  buf = read_conf_file(path)
  for (k,v) in buf:
    if k == configs:
      paths.append(v)
    else:
       config[k] = v

Если конфиг древовидный - сложнее. Нужно понять, как из path и какой-то дополнительной инфы получить позицию куда положить v в config. Для этого нужен будет обход графа в глубину (тогда ты будешь на каждом шаге перестраивать текущую позицию в дереве легко).

Norgat ★★★★★
()

Тебе нужна рекурсивная функция. Простейший пример:

#!/bin/bash

readconfig () {
  while read line
  do
    source $1
    if [[ ! -z $CONFIGS ]]
    then
      for CONFIG in $CONFIGS
      do
        readconfig $CONFIG
      done
    fi
  done < $1
}

readconfig $1
shell-script ★★★★★
()
Ответ на: комментарий от Norgat

А зачем такая сложность? Если я правильно понял задачу, достаточно просто перезаписывать значения из конфигов более высоко уровня, значениями, полученными из более низких.

shell-script ★★★★★
()
Ответ на: комментарий от shell-script

Использование рекурсии в лоб - практически всегда плохо или потенциально плохо. Тк может вызвать краш от слишком большой вложенности вызовов. К тому же, как показывает практика, чтение кода с рекурсией требует большего напряжения мозгов (если ты не пишешь на ЯП, где это норма) при одинаковом объеме кода (а код будет примерно одинаков в данном случае).

Оптимизацию tail recursion автоматически умеют не все VM. В том же python ее точно нет. Поэтому полагаться на компилятор в данном случае точно не стоит.

Norgat ★★★★★
()

Рекурсивная функция возвращающая дерево конфигов

AntonI ★★★★★
()

Всем спасибо.

@Norgat, @shell-script, максимальная вложенность небольшая - всего 10 порядков. Плюс так называемое дерево у меня не бинарное (ЕЯПП бинарное означает что у каждого родителя не больше 2 ответвлений 1 порядка), может быть 5 или даже больше ответвлений. Поэтому простая рекурсия действительно сработала нормально. За производительностью не гонюсь, поэтому оставил этот вариант. Спасибо за подсказки.

Entmatix
() автор топика

при этом они НЕ пересекаются с множеством конфигов верхнего уровня

Просто рекурсивный обход дерева/словаря. В пистоне заюзай defaultdict чтоб совсем просто было

upcFrost ★★★★★
()
Ответ на: комментарий от Norgat

а код будет примерно одинаков в данном случае

Это ещё надо доказать. Рекурсией тут легко реализовать видимость и передачу значений конфигурационных параметров, которые имеют свои значения в каждой ветке вглубь. При линейном разворачивании придётся возиться с обеспечением области видимости и сохранением и восстановлением значений.

vodz ★★★★★
()
Ответ на: комментарий от Norgat

Оптимизацию tail recursion автоматически умеют не все VM

Тут нет tail recursion вообще, так что с оптимизацией ни одна VM не справится.

theNamelessOne ★★★★★
()
Последнее исправление: theNamelessOne (всего исправлений: 1)
Ответ на: комментарий от Norgat

Уж что-то а чтение произвольного ввода это не то место где стоит экономить такты в ущерб прозрачности кода.

thunar ★★★★★
()

Мы добавили конфиг тебе в конфиг, чтобы ты мог читать конфиги, пока читаешь конфиги в конфигах?

Nervous ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.