742 votes

Supprimer le contenu d'un dossier en Python

Comment puis-je supprimer le contenu d'un dossier local en Python.
Le projet actuel est pour Windows mais j'aimerais voir *nix aussi.

19 votes

Pour *nix, pour être honnête, j'utiliserais simplement os.system('rm -rf folder')

11 votes

@TilakMaddy C'est une façon terrible, surtout si vous prenez le nom du dossier comme entrée utilisateur. Malheureusement, nous ne pouvons pas décoter les commentaires.

3 votes

Le commentaire de @TilakMaddy est une solution indolore, mais il n'aborde pas la partie "contenu". os.system('rm -rf folder/*') est la solution, en supposant qu'il n'y ait pas de .* le contenu...

637voto

Nick Stinemates Points 5642

Mis à jour pour ne supprimer que les fichiers et pour utiliser la méthode os.path.join() suggérée dans les commentaires. Si vous voulez supprimer tous le contenu du dossier, il suffit de supprimer l'instruction if.

import os 
folder = '/path/to/folder'
for the_file in os.listdir(folder):
    file_path = os.path.join(folder, the_file)
    try:
        if os.path.isfile(file_path):
            os.unlink(file_path)
    except Exception, e:
        print e

9 votes

Si vous travaillez avec un très grand répertoire, et particulièrement un répertoire réseau sous Windows, et que vous pouvez contrôler l'environnement dans lequel ce programme s'exécute, il peut être intéressant d'utiliser la fonction "os.scandir(folder)" de Py3.5 au lieu de listdir. La syntaxe est assez différente après cela, mais assez simple à mettre en œuvre ; je serai heureux de la poster si d'autres personnes le souhaitent.

5 votes

Je reçois un avertissement de pylint avec except Exception as e: qui se lit comme suit W0703: Catching too general exception Exception . Y a-t-il une exception plus spécifique à attraper ou dois-je l'ignorer ?

14 votes

@JohnHany, je crois que vous voulez attraper OSError.

448voto

Blueicefield Points 589

Vous pouvez simplement faire ceci :

import os
import glob

files = glob.glob('/YOUR/PATH/*')
for f in files:
    os.remove(f)

Vous pouvez bien sûr utiliser un autre filtre dans votre chemin, par exemple : /VOUS/PATH/*.txt pour supprimer tous les fichiers textes dans un répertoire.

20 votes

@Blueicefield * ne listera pas les fichiers cachés, nous devrions également ajouter glob.glob('path/.*)

5 votes

Bien que pour supprimer la liste des fichiers, cela me semble plus simple à faire : import sh; sh.rm(files)

5 votes

Alors que import sh; sh.rm(files) est plus joli, mais vous rencontrez des problèmes s'il y a plus de 1024 fichiers dans le répertoire.

330voto

Oli Points 5620

Essayez le module shutil

import shutil
shutil.rmtree('/path/to/folder')

Description : shutil.rmtree(path, ignore_errors=False, onerror=None)

Docstring : Supprimer récursivement une arbre de répertoire.

Si ignore_errors est défini, les erreurs sont ignorées ; sinon, si onerror est définie, il est appelé pour gérer l'erreur avec arguments (func, path, exc_info)func est os.listdir , os.remove ou os.rmdir ; le chemin est l'argument de cette qui a provoqué son échec ; et exc_info est un tuple renvoyé par sys.exc_info() . Si ignore_errors est faux et onerror est None une une exception est levée.

394 votes

Cela supprimera non seulement le contenu, mais aussi le dossier lui-même. Je ne pense pas que ce soit ce que la question demande.

4 votes

Je pense que c'est une bonne réponse. Pourquoi ne pas simplement supprimer le contenu et le dossier, puis refaire le dossier ?

69 votes

Parce que le nouveau répertoire et l'ancien ne seront pas les mêmes. Donc si un programme est assis dans le répertoire, attendant des choses, il aura le tapis sous ses pieds.

115voto

Iker Jimenez Points 3351

En complément de la réponse de mhawke, voici ce que j'ai mis en place. Il supprime tout le contenu d'un dossier mais pas le dossier lui-même. Testé sous Linux avec des fichiers, des dossiers et des liens symboliques, devrait fonctionner sous Windows également.

import os
import shutil

for root, dirs, files in os.walk('/path/to/folder'):
    for f in files:
        os.unlink(os.path.join(root, f))
    for d in dirs:
        shutil.rmtree(os.path.join(root, d))

1 votes

Pourquoi "marcher" et ne pas simplement énumérer le contenu du dossier ?

3 votes

C'est la bonne réponse si vous souhaitez également supprimer des répertoires. walk est utilisé pour séparer les répertoires des fichiers, qui doivent être traités différemment. Vous pouvez également utiliser os.listdir mais vous devrez vérifier manuellement si chaque entrée est un répertoire ou un fichier.

7 votes

C'est proche, mais os.walk et shutil.rmtree sont tous deux récursifs. os.walk n'est pas nécessaire puisque vous n'avez besoin que des fichiers et des répertoires de niveau supérieur dans le répertoire à nettoyer. Utilisez simplement une instruction if sur les éléments de os.listdir pour voir si chacun est un fichier ou un répertoire. Ensuite, utilisez respectivement remove/unlink et rmtree.

50voto

jgoeders Points 381

La réponse acceptée ne fonctionnera pas si vous voulez supprimer le contenu entier du dossier (y compris les sous-dossiers), car le dossier pourrait être non vide, ce qui entraînerait une erreur de os.unlink.

L'utilisation de rmtree et la recréation du dossier pourraient fonctionner, mais j'ai rencontré des erreurs en supprimant et en recréant immédiatement des dossiers sur des lecteurs réseau.

La solution proposée en utilisant walk ne fonctionne pas car elle utilise rmtree pour supprimer les dossiers et peut ensuite tenter d'utiliser os.unlink sur les fichiers qui étaient précédemment dans ces dossiers. Cela provoque une erreur.

La solution globale affichée tentera également de supprimer les dossiers non vides, ce qui entraînera des erreurs.

Je vous suggère d'utiliser :

folder_path = '/path/to/folder'
for file_object in os.listdir(folder_path):
    file_object_path = os.path.join(folder_path, file_object)
    if os.path.isfile(file_object_path):
        os.unlink(file_object_path)
    else:
        shutil.rmtree(file_object_path)

1 votes

Votre solution soulèvera également une erreur s'il existe un lien symbolique vers un autre répertoire.

0 votes

@Blueicefield - Pouvez-vous fournir un exemple. J'ai testé sous linux en utilisant un fichier et un dossier symlinkés, et je n'ai pas encore réussi à provoquer une erreur.

1 votes

@jgoeders - S'il y a un lien symbolique vers un répertoire, os.path.isfile() retournera False (parce qu'il suit les liens symboliques), et vous finirez par appeler shutil.rmtree() sur un lien symbolique, ce qui entraînera OSError("Cannot call rmtree on a symbolic link") .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X