2017-08-05 5 views
0

Supposons que j'ai un set de fichier renomme opérations:Changement de nom ensemble de fichiers lorsque les anciens conflits de noms avec de nouveaux noms dans python3

renames={(current_1,new_1),(current_2,new_2),...} 

Il est garanti que les fichiers current_1,current_2,... existent et que les nouveaux fichiers new_1,new_2,... sont uniques. Tous les fichiers sont des instances de pathlib.Path.

Cependant, ils peuvent être des fichiers qui sont actuellement nommés car un autre fichier doit être renommé: il peut exister une instance de current_i==new_j.

Quelle serait une manière élégante d'implémenter les opérations de renommer? Notez que je ne peux pas simplement parcourir renames et renommer chaque fichier, car je dois me préparer à une situation où le nouveau nom entre en conflit avec le nom d'un fichier qui doit encore être renommé.

Je suis spécifiquement à la recherche d'une implémentation en Python3, et j'aimerais que les renames soient conservées set dans le formulaire ci-dessus.

Une façon simple est de préfixe temporairement les fichiers:

temporal_prefix="a big string guaranteed not to appear in file names" 
for current,new in renames: 
    current.rename(current.with_name(temporal_prefix+current.name)) 
for current,new in renames: 
    current.with_name(temporal_prefix+current.name).rename(new) 

Mais ce n'est pas très élégant et il faut jusqu'à deux fois les opérations de fichiers nécessaires. Et trouver un bon préfixe peut être un problème en soi. Est-il possible de faire cela en une boucle, en utilisant le nombre minimum d'opérations sur les fichiers?

+0

Avec la persistance et le travail acharné, vous allez probablement résoudre ce problème. – wwii

Répondre

1

Il est inutile d'essayer d'être trop intelligent parce que renommer n'est pas une option coûteuse et l'erreur que vous obtenez quand un fichier existe est assez claire et peut être piégée et traitée. Vous pouvez même tester l'existence de chaque fichier en premier et éviter de piéger les erreurs si vous le souhaitez mais si vous pensez que la plupart des fichiers n'auront pas de problème c'est probablement une perte de temps

Utilisez simplement une structure de données comme une file d'attente Pour conserver vos renames, commencez à les traiter de la tête à la queue et en trouvant un échec dû à l'existant, remettez le renommer à la fin de la file d'attente pour que votre boucle revienne plus tard. La plupart des renommés réussiront probablement la première fois, ceux qui ne réussiront probablement pas la deuxième fois

Je n'ai pas posté d'exemple de code car je n'ai jamais touché de python dans ma vie (désolé). En pseudocode je voudrais:

+1

Attendez ... J'ai rencontré un problème avec ceci. Pour quelque chose comme [(A, B), (B, A)] où A et B existent ... la boucle ne sortira jamais. En général, cela se produit s'il existe une "chaîne" fermée de renom. – Saulpila

+0

C'est un bon point; il ressemble à un cas de bord étroit en ce qu'il est restreint aux paires qui cherchent à échanger les noms ou pire, les noms de cycle autour (ab, bc, ca). Peut-être étendre la logique de re-mise en file d'attente afin qu'elle renomme le fichier maintenant à un nom de fichier aléatoire temporaire et mettre cette nouvelle paire nom de tempname-> nom souhaité dans la file d'attente –

+0

Pseudocode ajouté –