Как получить все непосредственные подкаталоги в Python - PullRequest
117 голосов
/ 29 апреля 2009

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

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

Ответы [ 13 ]

196 голосов
/ 29 апреля 2009
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))]
65 голосов
/ 16 августа 2013

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

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

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

24 голосов
/ 07 сентября 2014

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

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

import os

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

print(dir_list)
18 голосов
/ 04 июля 2013
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)
11 голосов
/ 29 апреля 2009

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

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

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

9 голосов
/ 20 октября 2016

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

from glob import glob
subd = [s.rstrip("/") for s in glob(parent_dir+"*/")]
7 голосов
/ 29 апреля 2009

Использование модуля 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(...))
3 голосов
/ 29 апреля 2009

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

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

1 голос
/ 29 апреля 2009

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

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')
0 голосов
/ 06 мая 2019
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')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...