Question

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

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

Était-ce utile?

La solution

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

Autres conseils

Pourquoi personne n'a mentionné glob ? glob vous permet d'utiliser une extension de chemin d'accès de style Unix, et constitue la fonction de choix pour presque tout ce qui doit trouver plus d'un nom de chemin. C'est très simple:

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

Notez que glob renverra le répertoire avec la barre oblique finale (comme le ferait Unix), tandis que la plupart des solutions basées sur chemin omettront la barre oblique finale.

Vérifiez les " obtenir un liste de tous les sous-répertoires du répertoire en cours ".

Voici une version de Python 3:

import os

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

print(dir_list)
import os, os.path

Pour obtenir des sous-répertoires immédiats (chemin complet) 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 sous-répertoire (le plus récent):

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

os.walk est votre ami dans cette situation.

Directement de la documentation:

  

walk () génère les noms de fichier 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 dont la racine est située en haut du répertoire (y compris le sommet lui-même), il donne un tuple à 3 (dirpath, dirnames, noms de fichiers).

Cette méthode fait tout en une fois.

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

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

Certains commentateurs ayant demandé quels sont les avantages d'utiliser les bibliothèques de Twisted pour cela, je vais aller un peu au-delà de la question initiale.

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

Plus spécifiquement dans cet exemple: contrairement à la version standard de la bibliothèque, cette fonction peut être implémentée avec aucune importation . Les "sous-répertoires" La fonction est totalement générique, en ce sens qu'elle n'agit que sur son argument. Pour copier et déplacer les fichiers à l'aide de la bibliothèque standard, vous devez vous fier à l'option " open ". construit, " listdir ", peut-être" isdir " ou " os.walk " ou " shutil.copy ". Peut-être que " os.path.join " aussi. Sans oublier le fait que vous avez besoin d'une chaîne de caractères et d'un argument pour identifier le fichier réel. Jetons un coup d’œil à l’implémentation complète qui copiera le fichier "index.tpl " vers "index.html":

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

Les "sous-répertoires" La fonction ci-dessus peut fonctionner sur tout objet de type FilePath . Ce qui signifie, entre autres, les objets ZipPath . Malheureusement, ZipPath est en lecture seule pour le moment, mais il pourrait être étendu pour prendre en charge l'écriture.

Vous pouvez également transmettre vos propres objets à des fins de test. Afin de tester les API utilisant os.path suggérées ici, vous devez contrôler les noms importés et les dépendances implicites et effectuer généralement une 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(...))

Je viens d'écrire du code pour déplacer les machines virtuelles vmware, et j'ai finalement utilisé os.path et shutil pour effectuer la copie de fichiers entre 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 un moyen:

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 en tant que:

get_folders_in_directories_recursively (répertoire, index = 1) - > donne la liste des dossiers du premier niveau

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

Je dois mentionner la bibliothèque path.py , que j'utilise très souvent.

La récupération des sous-répertoires immédiats devient aussi simple que cela:

mon_dir.dirs ()

L'exemple de travail complet est le suivant:

from path import Path

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

subdirs = my_directory.dirs()
  

NB: my_directory peut toujours être manipulé en tant que chaîne, car Path est une sous-classe de chaîne, mais fournit un tas de méthodes utiles pour manipuler les chemins

.
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

La fonction child_dirs prend un chemin dans un répertoire et renvoie la liste des sous-répertoires immédiats qu'il contient.

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')
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top