Ordner in Python rekursiv löschen

200

Ich habe ein Problem beim Löschen leerer Verzeichnisse. Hier ist mein Code:

for dirpath, dirnames, filenames in os.walk(dir_to_search):
    //other codes

    try:
        os.rmdir(dirpath)
    except OSError as ex:
        print(ex)

Das Argument dir_to_searchist, wo ich das Verzeichnis übergebe, in dem die Arbeit erledigt werden muss. Das Verzeichnis sieht folgendermaßen aus:

test/20/...
test/22/...
test/25/...
test/26/...

Beachten Sie, dass alle oben genannten Ordner leer sind. Als ich dieses Skript die Ordner laufen 20, 25wird allein gelöscht! Aber die Ordner 25und 26werden nicht gelöscht, obwohl sie leere Ordner sind.

Bearbeiten:

Die Ausnahme, die ich bekomme, sind:

[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/29'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/29/tmp'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/28'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/28/tmp'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/26'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/25'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/27'
[Errno 39] Directory not empty: '/home/python-user/shell-scripts/s3logs/test/2012/10/27/tmp'

Wo mache ich einen Fehler?

Sriram
quelle
1
Sind Sie sicher, dass sie keine versteckten Dateien haben?
Jeff
Wird eine Ausnahme oder ein Traceback gedruckt? Wenn ja - es würde helfen, wenn Sie das der Frage
hinzufügen
@ Jeff: Ja, ich bin sicher. Tatsächlich lösche ich auf meinem Ubuntu-Computer rmdir /path/to/25th/folderdas gesamte Verzeichnis. Was bedeutet, dass das Verzeichnis leer ist!
Sriram
2
Mögliches Duplikat von Wie entferne / lösche ich einen Ordner, der mit Python nicht leer ist? von Frage und Antwort
Trevor Boyd Smith

Antworten:

388

Versuchen Sie shutil.rmtree:

import shutil
shutil.rmtree('/path/to/your/dir/')
Tomek
quelle
5
Löscht das rmtreedas gesamte Verzeichnis? Ich denke , es ist ähnlich demrm -Rf $DIR
sriram
6
Seien Sie vorsichtig, da rmtree auch die Dateien löscht. Wie gefragt, war die Frage, wie leere Verzeichnisse gelöscht werden können. Die Dokumente für os.walk geben ein Beispiel, das fast genau dieser Frage entspricht: import os for root, dirs, files in os.walk(top, topdown=False): for name in dirs: os.rmdir(os.path.join(root, name))
DaveSawyer
Python3-Versionsdokumente: docs.python.org/3/library/shutil.html#shutil.rmtree
Vladimir Oprya
26

Das Standardverhalten von os.walk()ist das Gehen von der Wurzel zum Blatt. Machen Sie sich topdown=Falseauf os.walk()den Weg vom Blatt zur Wurzel.

lqs
quelle
17

Hier ist mein reiner pathlibrekursiver Verzeichnis-Unlinker:

from pathlib import Path

def rmdir(directory):
    directory = Path(directory)
    for item in directory.iterdir():
        if item.is_dir():
            rmdir(item)
        else:
            item.unlink()
    directory.rmdir()

rmdir(Path("dir/"))
Mitchell
quelle
12

Versuchen Sie rmtree()in shutilder Python - Standardbibliothek

microo8
quelle
1
Löscht das rmtreedas gesamte Verzeichnis? Ich denke , es ist ähnlich demrm -Rf $DIR
sriram
2
aus den Dokumenten: "Löschen Sie einen gesamten Verzeichnisbaum. Der Pfad muss auf ein Verzeichnis verweisen (jedoch nicht auf einen symbolischen Link zu einem Verzeichnis). Wenn ignore_errors true ist, werden Fehler, die aus fehlgeschlagenen Entfernungen resultieren, ignoriert. Wenn false oder weggelassen werden, werden solche Fehler behandelt." indem sie einen von onerror angegebenen Handler aufrufen oder, wenn dies weggelassen wird, eine Ausnahme auslösen. "
Microo8
7

Verwenden Sie besser den absoluten Pfad und importieren Sie nur die Funktion rmtree, from shutil import rmtree da dies ein großes Paket ist. In der obigen Zeile wird nur die erforderliche Funktion importiert.

from shutil import rmtree
rmtree('directory-absolute-path')
Gajender
quelle
1
Sie würden dies dann als bezeichnen rmtree(); nichtshutil.rmtree()
Kevin Murphy
4

Nur für den nächsten, der nach einer Mikropython-Lösung sucht, funktioniert dies ausschließlich auf der Basis von OS (listdir, remove, rmdir). Es ist weder vollständig (insbesondere bei der Fehlerbehandlung) noch ausgefallen, funktioniert jedoch in den meisten Fällen.

def deltree(target):
    print("deltree", target)
    for d in os.listdir(target):
        try:
            deltree(target + '/' + d)
        except OSError:
            os.remove(target + '/' + d)

    os.rmdir(target)
Justus Wingert
quelle
3

Der Befehl (von Tomek gegeben) kann eine Datei nicht löschen , wenn sie schreibgeschützt ist . daher kann man verwenden -

import os, sys
import stat

def del_evenReadonly(action, name, exc):
    os.chmod(name, stat.S_IWRITE)
    os.remove(name)

if  os.path.exists("test/qt_env"):
    shutil.rmtree('test/qt_env',onerror=del_evenReadonly)
Monir
quelle
2
Wenn Sie versuchen, Ihren Code mit meinem eigenen Ordner zu löschen, wird die folgende Fehlermeldung angezeigt : NameError: name 'stat' is not defined. Wie wurde es definiert?
Nnako
1
Das stat-Modul definiert Konstanten und Funktionen zur Interpretation der Ergebnisse von os.stat (), os.fstat () und os.lstat (). Was Sie versuchen können: Importieren Sie OS, Sys von Stat Import *
Monir
0

Hier ist eine weitere reine Pathlib-Lösung , jedoch ohne Rekursion:

from pathlib import Path
from typing import Union

def del_empty_dirs(base: Union[Path, str]):
    base = Path(base)
    for p in sorted(base.glob('**/*'), reverse=True):
        if p.is_dir():
            p.chmod(0o666)
            p.rmdir()
        else:
            raise RuntimeError(f'{p.parent} is not empty!')
    base.rmdir()
pepoluan
quelle
-1

Hier ist eine rekursive Lösung:

def clear_folder(dir):
    if os.path.exists(dir):
        for the_file in os.listdir(dir):
            file_path = os.path.join(dir, the_file)
            try:
                if os.path.isfile(file_path):
                    os.unlink(file_path)
                else:
                    clear_folder(file_path)
                    os.rmdir(file_path)
            except Exception as e:
                print(e)
Tobias Ernst
quelle
-1

Für Linux-Benutzer können Sie den Shell-Befehl einfach pythonisch ausführen

import os
os.system("rm -r /home/user/folder_name")

wo rmsteht für entfernen und -rfür rekursiv

Garvit
quelle