Ich versuche, eine Python-Funktion zu schreiben, die alle leeren Verzeichnisse rekursiv löscht. Das bedeutet, wenn das Verzeichnis "a" nur "b" enthält, sollte "b" gelöscht werden, dann sollte "a" gelöscht werden (da es jetzt nichts enthält). Wenn ein Verzeichnis irgendetwas enthält, wird es übersprungen. Illustriert:Warum spiegelt os.walk() von Python das Löschen von Verzeichnissen nicht wider?
top/a/b/
top/c/d.txt
top/c/foo/
Vor diesem Hintergrund sind die drei Verzeichnisse „b“, „a“ und „foo“ gelöscht werden soll, als „foo“ und „b“ sind jetzt leer, und „a“ wird leer werden nach dem Löschen von "b".
Ich versuche dies über os.walk
und shutil.rmtree
zu tun. Leider löscht mein Code nur die erste Ebene von Verzeichnissen, aber nicht die neu geleerten Verzeichnisse.
Ich verwende den topdown=false
Parameter von os.walk
. Die documentation für os.walk
sagt, dass "Wenn topdown False ist, wird das Triple für ein Verzeichnis nach den Tripeln für alle seine Unterverzeichnisse generiert (Verzeichnisse werden von unten nach oben generiert)." Das sehe ich nicht.
Hier ist mein Code:
for root, dirs, files in os.walk(".", topdown=False):
contents = dirs+files
print root,"contains:",contents
if len(contents) == 0:
print 'Removing "%s"'%root
shutil.rmtree(root)
else:
print 'Not removing "%s". It has:'%root,contents
Wenn ich die Verzeichnisstruktur oben beschrieben haben, ist hier, was ich bekommen:
./c/foo contains: []
Removing "./c/foo"
./c contains: ['foo', 'd.txt']
Not removing "./c". It has: ['foo', 'd.txt']
./a/b contains: []
Removing "./a/b"
./a contains: ['b']
Not removing "./a". It has: ['b']
. contains: ['c', 'a']
Not removing ".". It has: ['c', 'a']
Beachten Sie, dass, obwohl ich "b" entfernt habe " a "wird nicht entfernt und denkt, dass es immer noch" b "enthält. Was mich verwirrt, ist, dass die Dokumentation für os.walk
besagt, dass es das Tripel für "./a" nach generiert, das das Tripel für "b" generiert. Meine Ausgabe schlägt anders vor. Ähnliche Geschichte für "./c". Es zeigt, dass es immer noch "foo" hat, obwohl ich es direkt aus dem Gate gelöscht hatte.
Was mache ich falsch? (Ich verwende Python 2.6.6.)
Ich würde nicht erwarten, os.Gehen Sie, um auf jeder Wiederholung der 'for' Schleife aktualisiert zu werden – jcfollower
Ich denke, das ist der Schlüssel. Das "Vorher" und das "Nachher" in der Dokumentation beziehen sich auf die Reihenfolge in dem resultierenden Array, das von "os.walk()" ausgegeben wird, und nicht auf eine zeitliche Reihenfolge aufeinanderfolgender Iterationen durch die for-Schleife. Die Tatsache, dass der Aufrufer im 'topdown = True'-Modus das' dirnames'-Argument ändern kann, ließ mich glauben, dass die Iteration beeinflusst werden könnte. – seanahern