Suppression récursive de dossiers en python

204

J'ai un problème avec la suppression de répertoires vides. Voici mon code:

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

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

L'argument dir_to_search est l'endroit où je passe le répertoire où le travail doit être effectué. Ce répertoire ressemble à ceci:

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

Notez que tous les dossiers ci-dessus sont vides. Lorsque j'exécute ce script, les dossiers20 , 25seul est supprimé! Mais les dossiers 25et 26ne sont pas supprimés, même s'il s'agit de dossiers vides.

Éditer:

Les exceptions que je reçois sont:

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

Où est-ce que je fais une erreur?

sriram
la source
1
êtes-vous sûr qu'ils n'ont pas de fichiers cachés?
Jeff
Une exception ou traceback est-elle imprimée? Si oui - il serait utile que vous
ajoutiez
@Jeff: Oui, j'en suis sûr. En fait, sur ma machine Ubuntu, j'ai essayé de rmdir /path/to/25th/foldersupprimer le répertoire entier. Ce qui signifie que ce répertoire est vide!
sriram
2
Duplication possible de Comment supprimer / supprimer un dossier qui n'est pas vide avec Python? des deux questions ET réponse
Trevor Boyd Smith

Réponses:

393

Essayez shutil.rmtree:

import shutil
shutil.rmtree('/path/to/your/dir/')
Tomek
la source
5
Est-ce que le rmtreerépertoire entier a été supprimé? Je suppose qu'il est similaire à celuirm -Rf $DIR
sriram
7
Soyez prudent car rmtree supprime également les fichiers. Comme demandé, la question était de savoir comment supprimer les répertoires VIDE. Les documents pour os.walk donnent un exemple qui correspond presque exactement à cette question: import os for root, dirs, files in os.walk(top, topdown=False): for name in dirs: os.rmdir(os.path.join(root, name))
DaveSawyer
Documents de version Python3: docs.python.org/3/library/shutil.html#shutil.rmtree
Vladimir Oprya
27

Le comportement par défaut de os.walk()est de marcher de la racine à la feuille. Mettre topdown=Falseà os.walk()marcher de la feuille à la racine.

lqs
la source
18

Voici mon pathlibdissociateur de répertoire purement récursif:

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/"))
mitch
la source
12

Essayez rmtree()à shutilpartir de la bibliothèque standard Python

microo8
la source
1
Est-ce que le rmtreerépertoire entier a été supprimé? Je suppose qu'il est similaire à celuirm -Rf $DIR
sriram
2
from docs: "Supprimer toute une arborescence de répertoires; le chemin doit pointer vers un répertoire (mais pas un lien symbolique vers un répertoire). Si ignore_errors est vrai, les erreurs résultant de suppressions échouées seront ignorées; si elles sont fausses ou omises, ces erreurs sont traitées en appelant un gestionnaire spécifié par onerror ou, si cela est omis, ils lèvent une exception. "
microo8
7

il vaut mieux utiliser le chemin absolu et importer uniquement la fonction rmtree from shutil import rmtree car il s'agit d'un gros package, la ligne ci-dessus n'importera que la fonction requise.

from shutil import rmtree
rmtree('directory-absolute-path')
Gajender
la source
1
Vous feriez alors référence à ceci comme rmtree(); passhutil.rmtree()
Kevin Murphy
4

Juste pour le prochain gars à la recherche d'une solution de micropython, cela fonctionne purement basé sur os (listdir, remove, rmdir). Il n'est ni complet (surtout dans la gestion des erreurs) ni fantaisiste, il fonctionnera cependant dans la plupart des cas.

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
la source
3

La commande (donnée par Tomek) ne peut pas supprimer un fichier, s'il est en lecture seule . par conséquent, on peut utiliser -

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
la source
2
lorsque vous essayez votre code avec mon propre dossier à supprimer, je reçois une erreur disant: NameError: name 'stat' is not defined. Comment a-t-il été défini?
nnako
1
Le module stat définit des constantes et des fonctions pour interpréter les résultats de os.stat (), os.fstat () et os.lstat (). ce que vous pouvez essayer: importer os, sys depuis stat import *
Monir
0

Voici une autre solution pure-pathlib , mais sans récursivité:

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
la source
-1

Voici une solution récursive:

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
la source
-1

Pour les utilisateurs de Linux, vous pouvez simplement exécuter la commande shell de manière pythonique

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

rmest synonyme de supprimer et -rpour récursive

Garvit
la source