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?


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

Antworten:


388

Versuchen Sie shutil.rmtree:

import shutil
shutil.rmtree('/path/to/your/dir/')

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


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.


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

12

Versuchen Sie rmtree()in shutilder Python - Standardbibliothek


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

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)

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)

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

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

-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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.