Как получить все непосредственные подкаталоги в Python

StackOverflow https://stackoverflow.com/questions/800197

  •  03-07-2019
  •  | 
  •  

Вопрос

Я пытаюсь написать простой скрипт Python, который будет копировать index.tpl в index.html во всех подкаталогах (за некоторыми исключениями).

Я увяз в попытке получить список подкаталогов.

Это было полезно?

Решение

import os
def get_immediate_subdirectories(a_dir):
    return [name for name in os.listdir(a_dir)
            if os.path.isdir(os.path.join(a_dir, name))]

Другие советы

Почему никто не упомянул glob? glob позволяет использовать расширение имен путей в стиле Unix, и я могу использовать их практически для всех задач, требующих поиска более одного пути.Это делает это очень легко:

from glob import glob
paths = glob('*/')

Обратите внимание, что glob вернет каталог с последней косой чертой (как это сделал бы Unix), в то время как большинство path основанные на этом решения будут опускать последнюю косую черту.

Проверять "Получение списка всех подкаталогов в текущем каталоге".

Вот версия Python 3:

import os

dir_list = next(os.walk('.'))[1]

print(dir_list)
import os, os.path

Чтобы получить (полный путь) непосредственные подкаталоги в каталоге:

def SubDirPath (d):
    return filter(os.path.isdir, [os.path.join(d,f) for f in os.listdir(d)])

Чтобы получить последний (самый новый) подкаталог:

def LatestDirectory (d):
    return max(SubDirPath(d), key=os.path.getmtime)

os.walk твой друг в этой ситуации.

Прямо из документации:

walk() генерирует имена файлов в дереве каталогов, проходя по дереву сверху вниз или снизу вверх.Для каждого каталога в дереве, корнем которого является вершина каталога (включая саму вершину), он дает тройной кортеж (путь к каталогу, имена каталогов, имена файлов).

Этот метод прекрасно делает все это за один раз.

from glob import glob
subd = [s.rstrip("/") for s in glob(parent_dir+"*/")]

Использование модуля FilePath Twisted:

from twisted.python.filepath import FilePath

def subdirs(pathObj):
    for subpath in pathObj.walk():
        if subpath.isdir():
            yield subpath

if __name__ == '__main__':
    for subdir in subdirs(FilePath(".")):
        print "Subdirectory:", subdir

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


Есть некоторая улучшенная документация в ветке, объясняющей преимущества FilePath;возможно, вам захочется это прочитать.

Более конкретно в этом примере:в отличие от версии стандартной библиотеки, эту функцию можно реализовать с помощью нет импорта.Функция «subdirs» является абсолютно универсальной, поскольку она не работает ни с чем, кроме своего аргумента.Чтобы копировать и перемещать файлы с помощью стандартной библиотеки, вам необходимо зависеть от "open"встроенный",listdir", возможно "isdir" или "os.walk" или "shutil.copy".Может быть "os.path.join" слишком.Не говоря уже о том, что вам нужна строка, передающая аргумент для идентификации фактического файла.Давайте посмотрим на полную реализацию, которая копирует «index.tpl» каждого каталога в «index.html»:

def copyTemplates(topdir):
    for subdir in subdirs(topdir):
        tpl = subdir.child("index.tpl")
        if tpl.exists():
            tpl.copyTo(subdir.child("index.html"))

Функция «subdirs» выше может работать на любом FilePath-подобный предмет.Это означает, среди прочего, ZipPath объекты.К сожалению ZipPath сейчас доступен только для чтения, но его можно расширить для поддержки записи.

Вы также можете передавать свои собственные объекты для целей тестирования.Чтобы протестировать предложенные здесь API, использующие os.path, вам придется повозиться с импортированными именами и неявными зависимостями и вообще прибегнуть к черной магии, чтобы ваши тесты заработали.С FilePath вы делаете что-то вроде этого:

class MyFakePath:
    def child(self, name):
        "Return an appropriate child object"

    def walk(self):
        "Return an iterable of MyFakePath objects"

    def exists(self):
        "Return true or false, as appropriate to the test"

    def isdir(self):
        "Return true or false, as appropriate to the test"
...
subdirs(MyFakePath(...))

Я только что написал код для перемещения виртуальных машин VMware и в итоге использовал os.path и shutil для копирования файлов между подкаталогами.

def copy_client_files (file_src, file_dst):
    for file in os.listdir(file_src):
            print "Copying file: %s" % file
            shutil.copy(os.path.join(file_src, file), os.path.join(file_dst, file))

Это не очень элегантно, но работает.

Вот один из способов:

import os
import shutil

def copy_over(path, from_name, to_name):
  for path, dirname, fnames in os.walk(path):
    for fname in fnames:
      if fname == from_name:
        shutil.copy(os.path.join(path, from_name), os.path.join(path, to_name))


copy_over('.', 'index.tpl', 'index.html')
def get_folders_in_directories_recursively(self, directory, index=0):
    folder_list = list()
    parent_directory = directory

    for path, subdirs, _ in os.walk(directory):
        if not index:
            for sdirs in subdirs:
                folder_path = "{}/{}".format(path, sdirs)
                folder_list.append(folder_path)
        elif path[len(parent_directory):].count('/') + 1 == index:
            for sdirs in subdirs:
                folder_path = "{}/{}".format(path, sdirs)
                folder_list.append(folder_path)

    return folder_list

Следующую функцию можно вызвать так:

get_folders_in_directories_recursily(directory, index=1) -> выдает список папок на первом уровне

get_folders_in_directories_recursily(directory) -> выдает все подпапки

Я должен упомянуть путь.py библиотека, которой я пользуюсь очень часто.

Получение непосредственных подкаталогов становится таким простым:

my_dir.dirs()

Полный рабочий пример:

from path import Path

my_directory = Path("path/to/my/directory")

subdirs = my_directory.dirs()

Примечание:my_directory по-прежнему можно манипулировать как строку, поскольку Path является подклассом строки, но предоставляет множество полезных методов для управления путями.

import glob
import os

def child_dirs(path):
     cd = os.getcwd()        # save the current working directory
     os.chdir(path)          # change directory 
     dirs = glob.glob("*/")  # get all the subdirectories
     os.chdir(cd)            # change directory to the script original location
     return dirs

А child_dirs функция принимает путь к каталогу и возвращает список непосредственные подкаталоги в этом.

dir
 |
  -- dir_1
  -- dir_2

child_dirs('dir') -> ['dir_1', 'dir_2']
import pathlib


def list_dir(dir):
    path = pathlib.Path(dir)
    dir = []
    try:
        for item in path.iterdir():
            if item.is_dir():
                dir.append(item)
        return dir
    except FileNotFoundError:
        print('Invalid directory')
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top