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?


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

Réponses:


393

Essayez shutil.rmtree:

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

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


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.


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

12

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


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

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)

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)

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

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

-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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.