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.
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))]
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.
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)
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)
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).
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(...))
Cette méthode fait bien tout en une seule fois.
from glob import glob
subd = [s.rstrip("/") for s in glob(parent_dir+"*/")]
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.
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')
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