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

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

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

Ответ 1

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))]

Ответ 2

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

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

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

Ответ 4

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)

Ответ 5

os.walk является вашим другом в этой ситуации.

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

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

Ответ 6

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

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

Ответ 7

Используя Twisted FilePath модуль:

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 -like. Что означает, среди прочего, объекты ZipPath. К сожалению, 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(...))

Ответ 8

Я просто написал код для перемещения виртуальных машин 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))

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

Ответ 9

Здесь один из способов:

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')

Ответ 10

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_recursively (directory, index = 1) → выдает список папок первого уровня

get_folders_in_directories_recursively (каталог) → дает все подпапки

Ответ 11

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']

Ответ 12

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

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

my_dir.dirs()

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

from path import Path

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

subdirs = my_directory.dirs()

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

Ответ 13

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')