Suppression de fichiers/dossiers

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour,

J'ai une structure de fichier ressemblant à ça :

1
2
3
4
5
.
└── 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.

Édité par Wizix

Mon projet : OpenPlane, un utilitaire en Java pour les pilotes, les vrais !

+0 -0

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 ?

Édité par Vayel

+0 -0
Staff

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.

Édité par nohar

I was a llama before it was cool

+0 -0
Auteur du sujet

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 !

Édité par Wizix

Mon projet : OpenPlane, un utilitaire en Java pour les pilotes, les vrais !

+0 -0
Auteur du sujet

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).

Mon projet : OpenPlane, un utilitaire en Java pour les pilotes, les vrais !

+0 -0
Staff

Cette réponse a aidé l'auteur du sujet

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.

Édité par nohar

I was a llama before it was cool

+1 -0
Auteur du sujet

Merci pour ton code, c'est super !
Seulement, il me sort une erreur :

1
2
3
4
5
6
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!

Mon projet : OpenPlane, un utilitaire en Java pour les pilotes, les vrais !

+0 -0
Staff

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.

I was a llama before it was cool

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

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