Suppression de fichiers/dossiers
Le problème exposé dans ce sujet a été résolu.
Bonjour,
J'ai une structure de fichier ressemblant à ça :
| .
└── 2015
└── 8
└── 21
└── 1.opf
|
Par exemple, je veux supprimer le fichier 1.opf
. Mais je veux aussi supprimer les dossiers parents si ils sont vident, et ce tant que l'on est pas arrivé au dossier .
qui est en nommé logbook
.
Voici ce que j'ai :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | # On sépare le chemin du fichier
path, opf_flight = os.path.split(path)
# On se déplace dans le dossier contenant le fichier
os.chdir(path)
# On supprime le fichier
os.remove(opf_flight)
# On récupère le nom du dossier actuel
current_dir = os.path.relpath('.','..')
# On remonte et on supprime si le dossier est vide
while current_dir != 'logbook':
# On remonte d'un dossier
os.chdir('..')
# On regarde si l'ancier dossier à des fichiers/dossiers
# Si non, on le supprime,
# Si oui, on le laisse
if os.listdir(current_dir) == []:
os.rmdir(current_dir)
# On récupère le dossier parent
current_dir = os.path.relpath('.','..')
|
Mais est-ce la meilleur façon de faire ? J'ai peur de faire une bêtise et de supprimer n'importe quoi (l'algo fonctionne mais j'ai l'impression que il est aussi capable de faire des bêtises).
Merci de votre aide.
Ca m'a l'air bon. Par contre, pourquoi utiliser os.path.relpath('.','..')
et non os.getcwd()
? C'est pour travailler avec des chemins relatifs ?
De plus, je déplacerais la ligne 14 après le bloc conditionnel. Non seulement ça ne sert à rien de remonter de dossier si tôt, mais ça porte même à confusion puisque de current_dir
ne désigne pas toujours le dossier courant. A moins que tu ne puisses pas supprimer le dossier dans lequel tu te situes ?
C'est bon mais ça fait quand même pas mal d'appels système pour peu de choses. Il ne devrait pas y avoir besoin de te déplacer dans les répertoires pour faire ça.
Dès que j'ai un peu de temps je te propose un code.
Salut,
os.path.relpath('.','..')
me permet d'obtenir juste le nom du dossier parent, rien de plus (et donc de vérifier si il vaut logbook
).
Mais si je déplace cette ligne, je peux toujours supprimer le dossier sachant que je serais toujours dedans ?
J'ai pas réussit à trouver d'autre moyen..
Hâte de lire ta version !
Déjà est-ce que tous les dossiers sont de la forme année/mois/jour ?
Ouip, sachant que les mois ont un indice de décalage (ils sont compris entre 0 pour janvier et 11 pour décembre).
Et sans 0 (Juin est donc 6
et non 06
et Janvier est 0
et non 00
).
Ok. Et quelle version de Python utilises-tu ? (Pour savoir si tu as pathlib
dans la bibliothèque standard)
Bon. J'ai pas de PC sous la main pour vérifier mais voilà ce que tu peux faire :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | from pathlib import Path
file_path = Path("/chemin/vers/ton/fichier.opf")
if file_path.exists():
# supprime le fichier
file_path.unlink()
for parent, _ in zip(file_path.parents, range(3)):
# On itère sur l'arborescence parente
# En ne remontant pas plus de 3 niveaux
try:
parent.rmdir()
except OSError:
# Le dossier n'est pas vide.
# Vérifie que l'exception levée est bien OSError
break
|
Je peux pas vérifier que l'exception levée est bien une OSError
, mais l'idée est là.
Au pire ça lèvera une autre exception mais ça ne supprimera rien que tu ne veuilles pas.
Edit : correction du code.
Merci pour ton code, c'est super !
Seulement, il me sort une erreur :
| Traceback (most recent call last):
File "/home/louis/Documents/Python/OpenPlane/openplane/gui/logbook/flight_view.py", line 221, in delete_flight
for parent in file_path.parents[:3]:
File "/usr/lib/python3.4/pathlib.py", line 531, in __getitem__
if idx < 0 or idx >= len(self):
TypeError: unorderable types: slice() < int()
|
Ne comprenant pas l'erreur, à part que ce n'est pas ordonnable, je ne peux la corriger.
Merci de ton aide!
Ok. Remplace la ligne par :
for parent, _ in zip(file_path.parents, range(3)):
Super ça fonctionne nickel !
Et c'est bien OSError
qui est envoyé.
Merci beaucoup de ton aide.
De rien.
D'une façon générale, si ton code utilise beaucoup le module os
, à moins que tu n'aies vraiment besoin de travailler à bas niveau pour une raison précise (faire des appels système directement pour rester thread-safe par exemple), ça doit te mettre la puce à l'oreille.
Le module os
est vraiment le niveau d'abstraction (et donc de confort) le plus bas en Python. En-dessous, t'es dans le noyau.
Connectez-vous pour pouvoir poster un message.
Connexion
Pas encore membre ?
Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte