Comment obtenir tous les sous-répertoires immédiats en Python

J'essaie d'écrire un script Python simple qui va copier un index.tpl à indexer.html dans tous les sous-répertoires (à quelques exceptions près).

Je suis embourbé en essayant d'obtenir la liste des sous-répertoires.

98
demandé sur the Tin Man 2009-04-29 02:59:11

10 réponses

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))]
175
répondu RichieHindle 2014-08-14 23:47:51

Pourquoi personne n'a mentionné glob? glob vous permet d'utiliser L'expansion de nom de chemin de style Unix, et est ma fonction go to pour presque tout ce qui a besoin de trouver plus d'un nom de chemin. Il le rend très facile:

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

Notez que glob renverra le répertoire avec la barre oblique finale (comme unix le ferait) alors que la plupart des solutions basées sur path ometront la barre oblique finale.

51
répondu ari 2015-05-04 18:16:38
import os, os.path

Pour obtenir (chemin complet) des sous-répertoires immédiats dans un répertoire:

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

Pour obtenir le dernier (le plus récent) sous-répertoire:

def LatestDirectory (d):
    return max(SubDirPath(d), key=os.path.getmtime)
16
répondu Milan 2013-07-04 16:41:33

Cochez " Obtenir une liste de tous les sous-répertoires du répertoire courant ".

Voici une version Python 3:

import os

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

print(dir_list)
13
répondu Geng Jiawen 2017-05-23 12:10:41

os.walk est votre ami dans cette situation.

Directement à partir de la documentation:

Walk () génère les noms de fichiers dans une arborescence de répertoires, en parcourant l'arborescence de haut en bas ou de bas en haut. Pour chaque répertoire de l'arborescence enracinée en haut du répertoire (y compris top lui-même), il donne un 3-tuple (dirpath, dirnames, filenames).

9
répondu Andrew Cox 2016-06-16 21:49:50

Utilisation du module FilePath de 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

Puisque certains commentateurs ont demandé quels sont les avantages de L'utilisation des bibliothèques de Twisted pour cela, je vais aller un peu au-delà de la question originale ici.


Il y a une documentation améliorée dans une branche qui explique les avantages de FilePath; vous voudrez peut-être lire cela.

Plus précisément dans cet exemple: contrairement à la version standard de la Bibliothèque, cette fonction peut être implémentée avec no les importations. La fonction "subdirs" est totalement Générique, En ce sens qu'elle ne fonctionne que sur son argument. Pour copier et déplacer les fichiers à l'aide de la bibliothèque standard, vous devez dépendre du "open" intégré, "listdir", peut-être "isdir" ou "os.walk" ou "shutil.copy". Peut-être" os.path.join " aussi. Sans parler du fait que vous avez besoin d'une chaîne passée un argument pour identifier le fichier réel. Jetons un coup d'oeil à l'implémentation complète qui copiera l'index de chaque répertoire.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"))

La fonction" subdirs " ci-dessus peut fonctionner sur n'importe quel objet de type FilePath. Ce qui signifie, entre autres choses, ZipPath objets. Malheureusement, ZipPath est en lecture seule en ce moment, mais il pourrait être étendu pour supporter l'écriture.

Vous pouvez également passer vos propres objets à des fins de test. Afin de tester le système d'exploitation.path-en utilisant les API suggérées ici, vous devez singe avec des noms importés et des dépendances implicites et généralement effectuer de la magie noire pour que vos tests fonctionnent. Avec FilePath, vous faites quelque chose comme ceci:

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(...))
6
répondu Glyph 2009-04-30 18:42:43

Cette méthode fait bien tout en une seule fois.

from glob import glob
subd = [s.rstrip("/") for s in glob(parent_dir+"*/")]
6
répondu SuaveSouris 2016-10-20 20:37:30

Je viens d'écrire du code pour déplacer les machines virtuelles VMware, et j'ai fini par utiliser os.path et shutil pour effectuer la copie de fichiers entre les sous-répertoires.

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

Ce n'est pas très élégant, mais ça marche.

2
répondu the Tin Man 2016-06-16 21:52:53

Voici une façon:

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')
1
répondu Scott Kirkwood 2009-04-29 14:26:20
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

La fonction suivante peut être appelée comme:

Get_folders_in_directories_recursively (directory, index = 1) - > donne la liste des dossiers au premier niveau

Get_folders_in_directories_recursively(répertoire) -> donne tous les sous-dossiers

0
répondu Kanish Mathew 2018-09-04 05:09:39