638 votes

La façon la plus pythique de supprimer un fichier qui peut ne pas exister

Je veux supprimer le fichier filename si elle existe. Est-il approprié de dire

if os.path.exists(filename):
    os.remove(filename)

Y a-t-il une meilleure façon de faire ? Une méthode en une ligne ?

8 votes

Voulez-vous essayer de supprimer un fichier s'il existe (et échouer si vous n'avez pas les permissions nécessaires) ou faire un effort pour le supprimer et ne jamais avoir d'erreur en pleine face ?

1 votes

Je voulais faire la première partie de ce que @DonalFellows a dit. Pour cela, je suppose que le code original de Scott serait une bonne approche ?

1 votes

Créez une fonction appelée unlink et le placer dans l'espace de nom PHP.

802voto

Matt Points 2704

Une façon plus pythique serait :

try:
    os.remove(filename)
except OSError:
    pass

Bien que cela prenne encore plus de lignes et soit très laid, cela évite l'appel inutile à os.path.exists() et suit la convention python de surutilisation des exceptions.

Il peut être utile d'écrire une fonction pour le faire à votre place :

import os, errno

def silentremove(filename):
    try:
        os.remove(filename)
    except OSError as e: # this would be "except OSError, e:" before Python 2.6
        if e.errno != errno.ENOENT: # errno.ENOENT = no such file or directory
            raise # re-raise exception if a different error occurred

26 votes

Mais cela passerait-il si l'opération de suppression échouait (système de fichiers en lecture seule ou autre problème inattendu) ?

174 votes

De plus, le fait que le fichier existe quand os.path.exists() est exécutée ne signifie pas qu'elle existe lorsque os.remove() est exécuté.

2 votes

@ScottWilson vous pouvez utiliser le module errno pour le déterminer. (Je vais mettre à jour ma réponse).

57voto

abought Points 827

os.path.exists renvoie à True pour les dossiers comme pour les fichiers. Pensez à utiliser os.path.isfile pour vérifier si le fichier existe à la place.

12 votes

Chaque fois que nous testons l'existence d'un fichier et que nous le supprimons en fonction de ce test, nous nous exposons à une condition de course. (Et si le fichier disparaît entre-temps ?)

47voto

Tim Keating Points 2942

Dans l'esprit de la réponse d'Andy Jones, que diriez-vous d'une authentique opération ternaire :

os.remove(fn) if os.path.exists(fn) else None

61 votes

Mauvaise utilisation des ternaires.

25 votes

@BrianHVB Parce que les ternaires sont là pour choisir entre deux valeurs en fonction d'une condition, pas pour faire du branchement.

2 votes

Je n'aime pas utiliser les exceptions pour le contrôle de flux. Elles rendent le code difficile à comprendre et, plus important encore, elles peuvent masquer une autre erreur (comme un problème de permission bloquant la suppression d'un fichier) qui provoquera un échec silencieux.

8voto

jotacor Points 29

Une autre façon de savoir si le fichier (ou les fichiers) existe(nt), et de le supprimer, est d'utiliser le module glob.

from glob import glob
import os

for filename in glob("*.csv"):
    os.remove(filename)

Glob trouve tous les fichiers qui pourraient sélectionner le motif avec un joker *nix, et boucle la liste.

0voto

Andy Jones Points 3275

Quelque chose comme ça ? Il tire parti de l'évaluation des courts-circuits. Si le fichier n'existe pas, l'ensemble de la conditionnelle ne peut pas être vraie, donc python ne prendra pas la peine d'évaluer la seconde partie.

os.path.exists("gogogo.php") and os.remove("gogogo.php")

31 votes

Ce n'est absolument pas "plus pythonique" - en fait, c'est une chose contre laquelle Guido met spécifiquement en garde, et qu'il qualifie d'"abus" des opérateurs booléens.

1 votes

Oh, je suis d'accord - une partie de la question demandait une réponse en une ligne et c'est la première chose qui m'est venue à l'esprit.

5 votes

On pourrait aussi en faire une ligne unique en supprimant simplement le trait de soulignement après les deux points Ou, encore mieux, Guide a ajouté à contrecoeur l'expression if pour empêcher les gens d'"abuser des opérateurs booléens", et il y a là une excellente occasion de prouver que l'on peut abuser de tout : os.remove("gogogo.php") if os.path.exists("gogogo.php") else None. :)

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