2009-04-28 4 views
89

Ich versuche, ein einfaches Python-Skript zu schreiben, das eine index.tpl in alle Unterverzeichnisse (mit einigen Ausnahmen) nach index.html kopieren wird.Wie bekomme ich alle direkten Unterverzeichnisse in Python

Ich bin stecken geblieben, indem ich versuche, die Liste der Unterverzeichnisse zu bekommen.

+8

Sie können feststellen, dass die akzeptierte Antwort auf diese früheren SO Frage das Problem löst: http://stackoverflow.com/questions/120656/directory-listing-in-python –

Antwort

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

os.walk ist Ihr Freund in dieser Situation.

Direkt aus der Dokumentation:

Fuß() erzeugt die Dateinamen in einem Verzeichnisbaum, durch den Baum zu Fuß entweder von oben nach unten oder von unten nach oben. Für jedes Verzeichnis in der Baumstruktur, die an der obersten Stelle des Verzeichnisses liegt (einschließlich top selbst), ergibt es ein 3-Tupel (dirpath, dirnames, filenames).

+1

Seien Sie sich bewusst sein, dass, wenn Sie nur wollen Die Unterverzeichnisse der ersten Ebene brechen dann nach dem ersten Satz von Rückgabewerten aus der os.walk-Iteration aus. – yoyo

6

über Twisted des FilePath-Modul:

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 

Da einige Kommentatoren gefragt haben, was die Vorteile der Verwendung von Twisted-Bibliotheken dafür ist, ich werde hier ein wenig über die ursprüngliche Frage gehen.


Da ist some improved documentation in einem Zweig, der die Vorteile von FilePath erklärt; Vielleicht möchtest du das lesen.

Genauer gesagt in diesem Beispiel: Im Gegensatz zur Standardversion der Bibliothek kann diese Funktion mit keine Importe implementiert werden. Die Funktion "Subdirs" ist völlig generisch, da sie nur auf ihrem Argument beruht. Um die Dateien mit der Standardbibliothek zu kopieren und zu verschieben, müssen Sie auf die eingebaute "open", "listdir", vielleicht "isdir" oder "os.walk" oder "shutil.copy" angewiesen sein. Vielleicht "" auch. Ganz zu schweigen von der Tatsache, dass Sie eine Zeichenfolge benötigen, die ein Argument übergeben wurde, um die tatsächliche Datei zu identifizieren. Lassen Sie uns einen Blick auf die vollständige Umsetzung nehmen, die jedes Verzeichnis des „index.tpl“ auf „index.html“ kopiert:

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

Die „subdirs“ -Funktion oben auf jedem FilePath -ähnlichen Objekt arbeiten können. Das bedeutet unter anderem Objekte. Leider ist ZipPath im Moment schreibgeschützt, aber es könnte erweitert werden, um das Schreiben zu unterstützen.

Sie können auch eigene Objekte zu Testzwecken übergeben. Um die hier vorgeschlagenen os.path-verwendenden APIs zu testen, musst du mit importierten Namen und impliziten Abhängigkeiten umgehen und generell schwarze Magie anwenden, um deine Tests zum Laufen zu bringen. Mit FilePath, tun Sie etwas wie folgt aus:

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

Da ich wenig mit Twisted zu tun habe, begrüße ich immer zusätzliche Informationen und Beispiele; Diese Antwort ist schön, dafür zu sehen. Da dieser Ansatz jedoch wesentlich mehr Arbeit erfordert als die Verwendung der integrierten Python-Module und eine Twisted-Installation, gibt es Vorteile bei der Verwendung, die Sie der Antwort hinzufügen könnten? –

+1

Glyphs Antwort wurde wahrscheinlich von der Tatsache inspiriert, dass TwistedLore auch .tpl-Dateien verwendet. – Constantin

+0

Nun, klar, ich erwarte nicht die spanische Inquisition :-) Ich nahm an "* .tpl" war eine generische Referenz auf eine abstrakte Erweiterung, die "Vorlage" bedeutet, und keine spezielle Twisted Vorlage (ich habe .tpl in viele Sprachen immerhin). Gut zu wissen. –

1

Hier ist eine Art und Weise:

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

-1: wird nicht funktionieren, da shuttil.copy in das aktuelle Verzeichnis kopiert wird, so dass Sie 'index.html' im aktuellen Verzeichnis einmal für jedes 'index.tpl' überschreiben, das Sie im Unterverzeichnisbaum finden . – nosklo

+0

Korrigiert den Code, danke! –

2

Ich schrieb einige Code vmware virtuelle Maschinen zu bewegen, und am Ende os.path und shutil mit Kopieren von Dateien zu erreichen zwischen Unterverzeichnissen.

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

Es ist nicht besonders elegant, aber es funktioniert.

13
import os, os.path 

Um (Voll Pfad) unmittelbare Unterverzeichnisse in einem Verzeichnis:

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

Um das neueste (neueste) Unterverzeichnis zu erhalten:

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

Warum hat niemand glob erwähnt? glob können Sie Unix-Stil Pfadnamen Erweiterung verwenden, und ist meine Funktion für fast alles, die mehr als einen Pfadnamen suchen müssen. Es macht es sehr einfach:

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

Beachten Sie, dass glob wird das Verzeichnis mit dem letzten Schrägstrich zurückzukehren (wie Unix würde), während die meisten path basierte Lösungen wird die endgültige Strich weglassen.

+2

Gute Lösung, einfach und funktioniert. Für diejenigen, die diesen letzten Schrägstrich nicht wollen, kann er diese 'paths = [p.replace ('/', '') für p in glob ('* /')]' verwenden. –

+3

Es könnte sicherer sein, einfach das letzte Zeichen mit '[p [: - 1] für p in Pfaden]' zu schneiden, da diese Ersetzungsmethode auch alle maskierten Schrägstriche im Dateinamen ersetzt (nicht, dass diese gewöhnlich sind). – ari

+2

Noch sicherer, verwenden Sie Streifen ('/'), um nachfolgende Schrägstriche zu entfernen.Auf diese Weise wird garantiert, dass Sie keine Zeichen ausschneiden, die keine Schrägstriche sind. –

9

Überprüfen Sie "Getting a list of all subdirectories in the current directory".

Hier ist eine Python 3 Version:

import os 

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

print(dir_list) 
+0

entfernen Es wäre mehr clear, wenn 'file_list' durch' dir_list' ersetzt wurde, weil '[1]' die Verzeichnisliste zurückgibt. – wisbucky

+0

@wisbucky Messepunkt, ich habe meine Antwort aktualisiert. –

+1

** Extrem schlau. ** Während Effizienz keine Rolle spielt (_... es tut total_), bin ich gespannt, ob dies oder der glob-basierte Generator Ausdruck '(s.rstrip ("/") für s in glob (parent_dir + "* /")) ist zeiteffizienter. Mein intuitiver Verdacht ist, dass eine 'stat()' -basierte 'os.walk()' Lösung * wesentlich schneller sein sollte als Shell-Style Globbing. Leider fehlt mir der Wille zu "zeitsteuern" und tatsächlich herausfinden. –

6

Diese Methode gut funktioniert das alles in einem Rutsch.

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