91 votes

La façon la plus simple de rm -rf en Python

Quel est le moyen le plus simple de faire l'équivalent de rm -rf en Python ?

1 votes

98voto

Josh Gibson Points 3735
import shutil
shutil.rmtree("dir-you-want-to-remove")

26 votes

Bien qu'utile, rmtree n'est pas équivalent : il se plante si vous essayez de supprimer un seul fichier.

0 votes

Pour une question plus générique du type "supprimer un répertoire non vide", où cette réponse conviendrait mieux, voyez : stackoverflow.com/questions/303200/

0 votes

rm -rf non-existing-folder fonctionne bien (il ne fait rien), mais votre script échouera

48voto

Gabriel Grant Points 1898

Bien qu'utile, rmtree n'est pas équivalent : il se trompe si vous essayez d'enlever un seul fichier, ce qui n'est pas le cas. rm -f ne le fait pas (voir l'exemple ci-dessous).

Pour contourner ce problème, vous devrez vérifier si votre chemin est un fichier ou un répertoire, et agir en conséquence. Quelque chose comme ceci devrait faire l'affaire :

import os
import shutil

def rm_r(path):
    if os.path.isdir(path) and not os.path.islink(path):
        shutil.rmtree(path)
    elif os.path.exists(path):
        os.remove(path)

Remarque : cette fonction ne gère pas les périphériques de type caractère ou bloc (ce qui nécessiterait l'utilisation de la fonction stat ).

Exemple dans différence de entre rm -f et de Python shutils.rmtree

$ mkdir rmtest
$ cd rmtest/
$ echo "stuff" > myfile
$ ls
myfile
$ rm -rf myfile 
$ ls
$ echo "stuff" > myfile
$ ls
myfile
$ python
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53) 
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import shutil
>>> shutil.rmtree('myfile')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/shutil.py", line 236, in rmtree
    onerror(os.listdir, path, sys.exc_info())
  File "/usr/lib/python2.7/shutil.py", line 234, in rmtree
    names = os.listdir(path)
OSError: [Errno 20] Not a directory: 'myfile'

Edit : gérer les liens symboliques ; noter les limitations selon le commentaire de @pevik

2 votes

Cette version ne fonctionne pas sur les liens symboliques vers les répertoires car python renvoie True sur os.path.isdir(symlink_to_directory)

0 votes

Bien vu, @pevik c'est corrigé. Merci !

1 votes

Cela ne fonctionne pas pour les répertoires où les permissions ne le permettent pas, mais vous êtes Root. À l'invite d'un shell, on vous demandera "override rw------ for File.txt ?" à moins que vous n'utilisiez le drapeau -f. Cela fonctionne silencieusement à l'invite alors qu'en haut, dans python, cela échoue.

6voto

pevik Points 521
import os
import shutil

def rm_r(path):
    if not os.path.exists(path):
        return
    if os.path.isfile(path) or os.path.islink(path):
        os.unlink(path)
    else:
        shutil.rmtree(path)

Version légèrement améliorée de la version de Gabriel Grant. Cela fonctionne aussi sur les liens symboliques vers les répertoires. Note : la fonction ne no gérer les périphériques de caractères et de blocs Un*x (il faudrait utiliser stat ).

1 votes

Vous pouvez probablement gérer les dispositifs en mettant le unlink dans le cas de repli ; faire rmtree si vous détectez un répertoire. C'est-à-dire que nous n'avons pas à tester spécifiquement les types de nœuds de périphériques.

0voto

Pogramist Points 33
def delite(filepath):

    import os, stat, sys
    def intertwin(_list):
        list1 = []
        for i in _list:
            list1 += i
        return list1
    allpath = os.walk(filepath)
    walk = []
    dirs = []
    path = []
    allfiles = []
    for i in allpath:
        walk.append(i)
    for i in walk:
        dirs.append(i[0])
    for _dir in dirs:
        os.chdir(_dir)
        files = os.listdir(_dir)
        files1 = []
        for i in files:
            files1.append(_dir + '\\' + i)
        files = files1[:]
        allfiles.append(files)
    allfiles = intertwin(allfiles)
    for i in allfiles:
        os.chmod(i, stat.S_IRWXU)
    allfiles.reverse()
    os.chdir(sys.path[0])
    for i in allfiles:
        try:
            os.remove(i)
        except:
            try:
                os.rmdir(i)
            except:
                pass
    os.chmod(filepath, stat.S_IRWXU)
    try:
        os.remove(filepath)
    except:
        os.rmdir(filepath)
        allfiles.reverse()
        os.chdir(sys.path[0])
        for i in allfiles:
            try:
                os.remove(i)
            except:
                try:
                    os.rmdir(i)
                except:
                    pass
        os.chmod(filepath, stat.S_IRWXU)
        try:
            os.remove(filepath)
        except:
            os.rmdir(filepath)

0 votes

, " " Supprime un dossier avec des fichiers ou un fichier, même si l'attribut "Lecture seule".

1 votes

En anglais, s'il vous plaît : Supprime un dossier avec des fichiers ou un fichier, même s'il est attribué "Lecture seule".

1 votes

C'était le traducteur, je ne connais pas bien l'anglais)).

0voto

Dan Points 142

Une solution de contournement pour Windows qui bloque la suppression d'un fichier consiste à tronquer le fichier :

outputFile = open(r"filename.txt","w") 
outputFile.truncate()
outputFile.close()
outputFile = open(r"filename.txt","a+") 

source : https://stackoverflow.com/a/2769090/6345724

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