Избегайте крошек в аргументе метода - PullRequest
0 голосов
/ 05 марта 2020

Метод (python) рекурсивно обходит файлы и должен перехватывать отсутствующие файлы. Я придумал это:

def find_recursively(fname, breadcrumbs, missing_files):
   try:
       txt = read(fname)
   except FileNotFoundError:
       missing_files.add((breadcrumbs.copy(), fname))
       return

   next_files = analyze(txt)
   for fn i next_files:
       find_recursively(fn, breadcrumbs + [fname], missing_files)

missing_files = []
breadcrumbs = []
find_recursively('first_file.txt', breadcrumbs, missing_files)

Но мне интересно, есть ли более разумный способ, позволяющий избежать загрязнения аргументов breadcrumbs и missing_files.

Ответы [ 2 ]

0 голосов
/ 06 марта 2020

@ решение Чепнера было прорывом. На самом деле это не нужно с аргументами breadcrumbs / missing_files, так как отсутствующие_файлы могут быть возвращены и добавлены с текущим файлом в for (..) l oop.

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

def traverse_includes_in_header(fn, do_stuff):
    # list of [breadcrumb 1..breadcrumb N, fn]
    missing_files = []
    try:
        txt = read()
    except FileNotFoundError:
        return [[fn]]

    includes = find_includes(txt)
    do_stuff(txt)
    for i in includes:
        mfs = traverse_includes_in_header(i, do_stuff)
        # prepend fn to every found missing file
        missing_files += [[fn] + mfl for mfl in mfs]

    return missing_files
0 голосов
/ 05 марта 2020

Вы можете избавиться от missing_files, если ваша функция вернет список пар хлебных крошек / пропущенных файлов. breadcrumbs не требуется имя вне функции и может быть инициализировано с использованием значения аргумента по умолчанию. Наличие аргумента - это функция , а не то, что нужно исключать.

def find_recursively(fname, breadcrumbs=None):
   if breadcrumbs is None:
       breadcrumbs = []

   try:
       txt = read(fname)
   except FileNotFoundError:
       # No copy is really needed, because we always pass a new
       # list on the recursive call, and never *modify*
       # the list we receive.
       return [(breadcrumbs, fname)]

   next_files = analyze(txt)
   new_breadcrumbs = breadcrumbs + [fname]
   return [mf for fn in next_files for mf in find_recursively(fn, new_breadcrumbs)]

missing_files = find_recursively('first_file.txt')
...