web-dev-qa-db-fra.com

Suppression de dossiers dans python récursivement

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 dossiers 20, 25 sont tous seuls supprimés! Mais les dossiers 25 et 26 ne sont pas supprimés, même s'il s'agit de dossiers vides.

Modifier:

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?

165
sriram

Essayez shutil.rmtree :

_import shutil
shutil.rmtree('/path/to/your/dir/')
_
327
Tomek

Le comportement par défaut de os.walk() est de marcher de la racine à la feuille. Définissez topdown=False dans os.walk() pour passer de la feuille à la racine.

26
lqs

Essayez rmtree dans shutil . dans la bibliothèque python std

12
microo8

Un peu tard pour le spectacle mais voici mon pur Pathlib annuaire récursif unlinker

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

rmdir(pathlib.Path("dir/"))
10
mitch

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

from shutil import rmtree
rmtree('directory-absolute-path')
7
Gajender

Juste pour le prochain gars cherchant une solution de micropython, cela fonctionne uniquement sur os (listdir, remove, rmdir). Il n'est ni complet (en particulier dans le traitement des erreurs) ni fantaisie, cela fonctionnera 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
Justus Wingert

La commande (donnée par Tomek) impossible de supprimer un fichier, si c'est lecture seule. donc, 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
Monir

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)
0
Tobias Ernst

Voici ne 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()
0
pepoluan