Как перечислить все файлы и папки целевого файла или каталога в Python?Python

Программы на Python
Ответить
Anonymous
 Как перечислить все файлы и папки целевого файла или каталога в Python?

Сообщение Anonymous »

Описание функции
Я пытаюсь написать функцию, которая принимает цель ввода, которая является целью пути в файловой системе. Это может быть сам каталог или файл.
Эта функция должна возвращать список всех файлов и папок, которые являются подцелями ниже целевого.. p>
Чтобы объяснить более подробно:
  • Если целью является файл, возвращаемое значение представляет собой список длина 1 с полным путем к цели.
  • Если цель является каталогом, возвращаемое значение должно быть списком, содержащим рекурсивное подсодержимое target, включая саму цель.
  • Элементы должны возвращаться в отсортированном порядке
  • Элементы должны возвращаться таким образом, чтобы можно было различать, какие возвращаемые элементы являются путями к файлам, а какие возвращаемые элементы являются путями к каталогам.
Существующие вопросы в стеке Переполнение
По поводу переполнения стека есть похожие вопросы, но ни один из них не охватывает этот случай.
Вот краткое описание:
  • Как вывести список всех файлов каталога?
  • Получение списка все подкаталоги текущего каталога
Ответы в обоих вопросах предполагается, что целью является каталог. Они не работают, если целью является файл. Кроме того, в первом вопросе возвращаются только файлы. Не каталоги. Во втором вопросе возвращаются только каталоги. Не файлы.
Стратегия реализации
Эту функцию следует разбить на три этапа.
  • Первый шаг должен получить относительные пути.
  • Вторым шагом должна быть операция сопоставления, которая преобразует относительные пути в абсолютные или полные пути.< /li>
    Третий шаг должен отсортировать возвращаемые элементы.
Эта конструкция обеспечит высокую степень гибкости, например, каждая функция выполняет одну работу, а функции можно компоновать. Это хороший дизайн программного обеспечения, некоторые назвали бы его чистым дизайном.
Однако, возможно, лучший дизайн мог бы разделить коллекцию файлов и каталогов на две независимые функции. это приведет к снижению производительности, поскольку цель придется пройти дважды.
Выбор базовой функции
Существует несколько вариантов базовой функции что я знаю. У нас есть: Я не уверен, какой именно вариант будет лучшим выбором.< /p>
Попытка решения
Я начал с попытки реализовать это. Это довольно сложно, поскольку входные данные должны быть целевым путем, и изначально неизвестно, является ли это файлом или каталогом.
Это означает, что логика уровня интерфейса должна быть другой. к рекурсивным вызовам.
Я не могу найти простого и элегантного решения этой проблемы. Это заставляет меня думать, что, возможно, есть лучший способ сделать это, но я просто не понимаю, что это такое.
Опираясь на этот пример:

Код: Выделить всё

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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»