Domanda

Sto cercando di scrivere un semplice script Python che copi un index.tpl in index.html in tutte le sottodirectory (con alcune eccezioni).

Mi sto impantanando cercando di ottenere l'elenco delle sottodirectory.

È stato utile?

Soluzione

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

Altri suggerimenti

Perché nessuno ha menzionato glob ? glob ti consente di utilizzare l'espansione del percorso in stile Unix, ed è il mio go per funzionare per quasi tutto ciò che ha bisogno di trovare più di un nome di percorso. Lo rende molto semplice:

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

Nota che glob restituirà la directory con la barra finale (come farebbe unix) mentre la maggior parte delle soluzioni basate su percorso ometterà la barra finale.

Controlla " Ottenere un elenco di tutte le sottodirectory nella directory corrente " ;.

Ecco una versione di Python 3:

import os

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

print(dir_list)
import os, os.path

Per ottenere sottodirectory immediate (percorso completo) in una directory:

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

Per ottenere la sottodirectory più recente (più recente):

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

os.walk è tuo amico in questa situazione.

Direttamente dalla documentazione:

  

walk () genera i nomi dei file in un albero di directory, camminando l'albero in alto o in basso. Per ogni directory nell'albero radicata nella directory top (incluso top stessa), produce una 3 tupla (dirpath, dirnames, nomi di file).

Questo metodo fa bene tutto in una volta.

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

Utilizzando il modulo FilePath di 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

Poiché alcuni commentatori hanno chiesto quali siano i vantaggi dell'utilizzo delle librerie di Twisted per questo, andrò un po 'oltre la domanda originale qui.


C'è della documentazione migliorata in un ramo che spiega i vantaggi di FilePath; potresti volerlo leggere.

Più precisamente in questo esempio: a differenza della versione standard della libreria, questa funzione può essere implementata con nessuna importazione . "Subdir" " la funzione è totalmente generica, in quanto non opera altro che il suo argomento. Per copiare e spostare i file utilizzando la libreria standard, devi dipendere da " open " builtin, " listdir " ;, forse " isdir " o " os.walk " o " shutil.copy " ;. Forse " os.path.join " pure. Per non parlare del fatto che è necessario che una stringa abbia passato un argomento per identificare il file effettivo. Diamo un'occhiata all'implementazione completa che copierà ogni directory " index.tpl " a " index.html " ;:

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

Il " subdir " la funzione sopra può funzionare su qualsiasi oggetto FilePath . Il che significa, tra l'altro, oggetti ZipPath . Purtroppo ZipPath è di sola lettura in questo momento, ma potrebbe essere esteso per supportare la scrittura.

Puoi anche passare i tuoi oggetti a scopo di test. Per testare le API che utilizzano os.path suggerite qui, devi cercare i nomi importati e le dipendenze implicite ed eseguire generalmente la magia nera per far funzionare i test. Con FilePath, fai qualcosa del genere:

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

Ho appena scritto del codice per spostare le macchine virtuali VMware e ho finito con os.path e shutil per realizzare la copia dei file tra le sottodirectory.

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

Non è terribilmente elegante, ma funziona.

Ecco un modo:

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 seguente funzione può essere chiamata come:

get_folders_in_directories_recursively (directory, index = 1) - > fornisce l'elenco delle cartelle di primo livello

get_folders_in_directories_recursively (directory) - > fornisce tutte le sottocartelle

Devo menzionare la libreria path.py , che utilizzo molto spesso.

Il recupero delle sottodirectory immediate diventa così semplice:

my_dir.dirs ()

L'esempio di lavoro completo è:

from path import Path

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

subdirs = my_directory.dirs()
  

NB: my_directory può ancora essere manipolata come una stringa, poiché Path è una sottoclasse di string, ma fornisce una serie di metodi utili per manipolare i percorsi

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 funzione child_dirs prende un percorso in una directory e restituisce un elenco delle sottodirectory immediate in essa.

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')
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top