Я пытаюсь написать функцию, которая принимает цель ввода, которая является целью пути в файловой системе. Это может быть сам каталог или файл.
Эта функция должна возвращать список всех файлов и папок, которые являются подцелями ниже целевого.. p>
Чтобы объяснить более подробно:
- Если целью является файл, возвращаемое значение представляет собой список длина 1 с полным путем к цели.
- Если цель является каталогом, возвращаемое значение должно быть списком, содержащим рекурсивное подсодержимое target, включая саму цель.
- Элементы должны возвращаться в отсортированном порядке
- Элементы должны возвращаться таким образом, чтобы можно было различать, какие возвращаемые элементы являются путями к файлам, а какие возвращаемые элементы являются путями к каталогам.
По поводу переполнения стека есть похожие вопросы, но ни один из них не охватывает этот случай.
Вот краткое описание:
- Как вывести список всех файлов каталога?
- Получение списка все подкаталоги текущего каталога
Стратегия реализации
Эту функцию следует разбить на три этапа.
- Первый шаг должен получить относительные пути.
- Вторым шагом должна быть операция сопоставления, которая преобразует относительные пути в абсолютные или полные пути.< /li>
Третий шаг должен отсортировать возвращаемые элементы.
Однако, возможно, лучший дизайн мог бы разделить коллекцию файлов и каталогов на две независимые функции. это приведет к снижению производительности, поскольку цель придется пройти дважды.
Выбор базовой функции
Существует несколько вариантов базовой функции что я знаю. У нас есть:
Код: Выделить всё
os.listdirКод: Выделить всё
os.scandirКод: Выделить всё
os.walkКод: Выделить всё
os.fwalk- Может быть, другие?
Попытка решения
Я начал с попытки реализовать это. Это довольно сложно, поскольку входные данные должны быть целевым путем, и изначально неизвестно, является ли это файлом или каталогом.
Это означает, что логика уровня интерфейса должна быть другой. к рекурсивным вызовам.
Я не могу найти простого и элегантного решения этой проблемы. Это заставляет меня думать, что, возможно, есть лучший способ сделать это, но я просто не понимаю, что это такое.
Опираясь на этот пример:
Код: Выделить всё
import os
def fast_scandir(target_dir: str) -> list[str]:
items = []
for f in os.scandir(target_dir):
if f.is_dir():
items.extend(fast_scandir(f.path))
if f.is_file():
items.append(f.path)
items.sort()
return items
Код: Выделить всё
# Interface level, takes a `target`, don't know if it is a file or dir
def fast_scandir_3(target:str) -> list[tuple[str, str]]:
items:list[tuple[str, str]] = []
if os.path.isfile(target):
item = ('f', target)
items.extend(_fast_scandir_3_impl(item))
elif os.path.isdir(target):
item = ('d', target)
items.extend(_fast_scandir_3_impl(item))
return items
Код: Выделить всё
# Implementation layer
# TODO: will add sorting with `sorted` and fully-qualified paths later
def _fast_scandir_3_impl(target:tuple[str, str]) -> list[tuple[str, str]]:
items:list[tuple[str, str]] = []
items.append(target)
if target[0] == 'f':
pass
elif target[0] == 'd':
target_path = target[1]
for subtarget in os.listdir(target_path):
if os.path.isfile(subtarget):
target = ('f', subtarget)
items.extend(_fast_scandir_3_impl(target))
elif os.path.isdir(subtarget):
target = ('d', subtarget):
items.extend(_fast_scandir_3_impl(target ))
return items
Код: Выделить всё
def _fast_scandir_3_fully_qualified_impl(target:tuple[str, str]) -> list[tuple[str, str]]:
return (
list(
map(
lambda item: (item[0], os.path.abspath(item[1])),
_fast_scandir_3_impl(target),
)
)
)
Код: Выделить всё
def _fast_scandir_3_fully_qualified_sorted_impl(target:tuple[str, str]) -> list[tuple[str, str]]:
return sorted(_fast_scandir_3_fully_qualified_impl(target), key=lambda pair: pair[1])
Кроме того, остается еще несколько вопросов:
p>
- Является ли эта реализация со listdir правильным выбором?
- Сортировка является наиболее эффективным способом отсортировать возвращенные товары? (Не показано в приведенной выше реализации.)
Подробнее здесь: https://stackoverflow.com/questions/792 ... -in-python
Мобильная версия