Précédent   Forum du club des développeurs et IT Pro > Autres langages > Python & Zope > Général Python
Général Python Forum d'entraide sur les fondamentaux du langage Python, syntaxe, POO, bibliothèque standard, ...
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 10/12/2012, 11h47   #1
piloubu
Invité de passage
 
Homme
Inscription : février 2012
Messages : 10
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : février 2012
Messages : 10
Points : 2
Points : 2
Par défaut Caractères spéciaux dans une adresse de répertoire

Bonjour à tous,

Tout d'abord je tiens à préciser que je ne suis malheureusement pas un crack en programmation. Il va peut-être faloir être patient

J'ai un petit soucis avec les caractères spéciaux. J'ai bien compris qu'il s'agit d'une différence d'encodage mais je n'arrive pas à m'en sortir. Voici le scénario:

J'ai écrit un petit script dans lequel je définis en premier un répertoire soucre et un répertoire destination:

SOURCE = "O:\\Rep1\\Sous-Rep1\\probläm\\"
ARCHIVE = "O:\\Rep2\\Sous-Rep2\\probläm\\"

L'ideé est d'aller chercher un fichier dans le répertoire source, de faire quelques opérations basiques dessus et de le sauvegarder dans le répertoire destination. Tout marche parfaitement à un détail près : les noms de ces répertoires contiennent des caractères spéciaux et je n'ai pas le droit de les changer (c'est sur un disque réseau dans mon entreprise et plusieurs personnes utilisent ces répertoires).

Du coup à l'exécution j'ai ça:

WindowsError: [Error 3] Le chemin d'accès spécifié est introuvable: 'O:\\Rep1\\Sous-Rep1\\probl\xe4m\\'

Merci de votre aide!
piloubu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/12/2012, 13h16   #2
VinsS
Membre Expert
 
Homme
Inscription : octobre 2008
Messages : 936
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Belgique

Informations forums :
Inscription : octobre 2008
Messages : 936
Points : 1 402
Points : 1 402
Salut,

Essayes avec ceci:
Code :
1
2
3
 
src = "O:\\Rep1\\Sous-Rep1\\probläm\\"
SOURCE = src.encode(sys.getfilesystemencoding(), 'replace')
Pas de Windows pour vérifier, mais c'est ce que j'utilise sous Linux.
__________________
Vincent
Oqapy . Qarte . PaQager
VinsS est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/12/2012, 13h48   #3
piloubu
Invité de passage
 
Homme
Inscription : février 2012
Messages : 10
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : février 2012
Messages : 10
Points : 2
Points : 2
Salut,

Merci pour ta réponse! J'ai essayé mais j'ai eu le doit à ceci :

SOURCE = src.encode(sys.getfilesystemencoding(), 'replace') NameError: name 'src' is not defined

Y'a-t'il une librairie spéciale à charger?

Pour le moment dans mes "import" j'ai:

import os
import shutil
import re
import sys

Merci!
piloubu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/12/2012, 14h41   #4
VinsS
Membre Expert
 
Homme
Inscription : octobre 2008
Messages : 936
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Belgique

Informations forums :
Inscription : octobre 2008
Messages : 936
Points : 1 402
Points : 1 402
Relis mon exemple, j'ai divisé ta ligne SOURCE = ... en deux lignes.
__________________
Vincent
Oqapy . Qarte . PaQager
VinsS est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/12/2012, 14h53   #5
piloubu
Invité de passage
 
Homme
Inscription : février 2012
Messages : 10
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : février 2012
Messages : 10
Points : 2
Points : 2
ah désolé!

Du coup j'ai corrigé ça et j'ai un autre type d'erreur

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 17: ordinal not in range(128)

Une idée?

Merci de ton aide!

(pour information, les vrais noms de répertoires que j'utilise ne sont pas ceux-indiqués dans ce post pour des raisons de confidentialité en accord avec la politique de mon entreprise. Mais le caractère spécial qui pose problème est bien un ä)
piloubu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/12/2012, 15h23   #6
piloubu
Invité de passage
 
Homme
Inscription : février 2012
Messages : 10
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : février 2012
Messages : 10
Points : 2
Points : 2
Bonjour,

Je relance ma question... Ets-ce que quelqu'un a une idée pour contourner ce problème?

Merci!

Citation:
Envoyé par piloubu Voir le message

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 17: ordinal not in range(128)
piloubu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/12/2012, 15h38   #7
wiztricks
Expert Confirmé Sénior
 
Inscription : juin 2008
Messages : 3 693
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 3 693
Points : 4 521
Points : 4 521
Salut,

La plupart des erreurs que vous avez sont dues à la version de Python que vous utilisez (version 2.x).
Si vous n'avez pas de bonnes raisons pour rester sous cette version, utilisez/apprenez avec une 3.2 ou mieux une 3.3.

Si vous devez restez en 2.7...
open accepte les noms de fichiers Unicode.
Dans le cas de litéraux, il faut les préfixer par un "u":
Code :
1
2
3
>>> z = open(u'élément.txt', 'r')
>>> z.name
u'\xe9l\xe9ment.txt'
et inclure dans le code source l'encoding utilisé pour coder la chaîne de caractères (le défaut pour Python3 est utf-8, pour Python2 c'est ASCII)
- W
__________________
Architectures Post-Modernes
wiztricks est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/12/2012, 14h34   #8
piloubu
Invité de passage
 
Homme
Inscription : février 2012
Messages : 10
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : février 2012
Messages : 10
Points : 2
Points : 2
Bonjour

Citation:
Envoyé par wiztricks Voir le message

utilisez/apprenez avec une 3.2 ou mieux une 3.3.
J'ai téléchargé python 3.3 pour windows. Il semble effectivement que cette modification ait fait avancer un peu la chose car le caractère spécial ne semble plus poser de problème.

MAIS

J'ai maintenant un autre soucis llié à cette modification. Mon programme est censé regarder tous les fichiers qui sont dans le répertoire source, et pour ceux dont le nom a une certaine forme, les déplacer dans un répertoire de destination qui est de la forme source+nom de fichier.

grosso modo le code est le suivant:

SOURCE = "O:\\Rep1\\Sous-Rep1\\probläm\\"

for file_name in os.listdir(SOURCE):
if re.match(r'^(AB_01).*\.txt$',file_name):
FINAL_DEST = SOURCE+file_name[6:8]+"\\"
shutil.move(SOURCE+file_name,FINAL_DEST)
Je ne sais pas si c'est très clair

Toujours est-il qu'avec cette nouvelle version de python j'ai maintenant:

if re.match(r'^(VD_61).*\.txt$',file_name):
File "C:\Python33\lib\re.py", line 156, in match
return _compile(pattern, flags).match(string)
TypeError: can't use a string pattern on a bytes-like object


Et là j'ai un peu de mal à voit comment faire: si je convertis mon nom de fichier en bytes-like object, comment faire pour la concaténation de chaine qui définit le répertoire FINAL_DEST?

Merci de votre aide!
piloubu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/12/2012, 15h05   #9
chticricri
Membre habitué
 
Homme Christian Havard
Développeur informatique
Inscription : mai 2011
Messages : 100
Détails du profil
Informations personnelles :
Nom : Homme Christian Havard
Localisation : Belgique

Informations professionnelles :
Activité : Développeur informatique
Secteur : Conseil

Informations forums :
Inscription : mai 2011
Messages : 100
Points : 139
Points : 139
Bonjour,

C'est bizarre mais, chez moi, quand j'essaie de reproduire ton problème
avec python 3.3, le code fonctionne.

Pour bien faire, il faudrait un exemple minimal un peu plus complet. Par exemple, quel est l'encoding du fichier source (celui qui contient le programme) ?

Au passage, il est plus simple avec python de taper les path à la UNIX (c:/doc/fichier.txt plutôt que c:\\doc\\fichier.txt
chticricri est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/12/2012, 15h58   #10
wiztricks
Expert Confirmé Sénior
 
Inscription : juin 2008
Messages : 3 693
Détails du profil
Informations forums :
Inscription : juin 2008
Messages : 3 693
Points : 4 521
Points : 4 521
Si vous êtes en 3+, r'^(AB_01).*\.txt$' est unicode.
Par contre os.listdir retourne des bytes que lorsque son argument est bytes.
Et telle que construite, SOURCE devrait être un str unicode.

Impossible de comprendre cette erreur avec les informations que vous donnez!
- W
__________________
Architectures Post-Modernes
wiztricks est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/12/2012, 14h14   #11
piloubu
Invité de passage
 
Homme
Inscription : février 2012
Messages : 10
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : février 2012
Messages : 10
Points : 2
Points : 2
Citation:
Envoyé par wiztricks Voir le message
Si vous êtes en 3+, r'^(AB_01).*\.txt$' est unicode.
Par contre os.listdir retourne des bytes que lorsque son argument est bytes.
Et telle que construite, SOURCE devrait être un str unicode.

Impossible de comprendre cette erreur avec les informations que vous donnez!
- W
Je vais essayer d'être plus clair mais ce n'est pas simple car il y a pas mal de choses confidentielles. Voici la structure quasi entière du code. Mais ce ne doit pas être très rigoureux... Pardonnez par avance la facon dont tout celà est écrit (et vous comprendrez mon faible niveau en programmation).


import os
import shutil
import re
import sys

SOURCE = "O:\\Rep1\\Sous-Rep1\\probläm\\"
ARCHIVE = "O:\\Rep2\\Sous-Rep2\\probläm\\"

def main():

#Task 1 : Remove useless files, and keep AB files
for file_name in os.listdir(SOURCE):
if re.match(r'^(AB_01).*\.txt$',file_name):
length=len(file_name)
print(file_name)
for j in range (length-3):
if (file_name[5]=='0'):
FINAL_DEST = ARCHIVE+"AB_01"+file_name[6:8]+"\\"
else:
FINAL_DEST = ARCHIVE+"AB_01 "+file_name[5:8]+"\\"
if not os.path.exists(FINAL_DEST):
os.mkdir(FINAL_DEST)
print('Creating '+FINAL_DEST+'\n')
if not os.path.exists(FINAL_DEST+file_name):
shutil.move(SOURCE+file_name,FINAL_DEST)
print('Archiving in '+FINAL_DEST+'\n')
elif os.path.exists(FINAL_DEST+file_name):
os.remove(SOURCE+file_name)
print('File already exists \n'+'Deleting file\n')
break
else :
print('File not treated! Please check the name of the file manually'+'\n')
elif
os.remove(SOURCE+file_name)
print(file_name+' is not a AB_01file\n'+'Deleting '+file_name+'\n')
main()


Encore merci du coup de main!
piloubu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/12/2012, 16h09   #12
chticricri
Membre habitué
 
Homme Christian Havard
Développeur informatique
Inscription : mai 2011
Messages : 100
Détails du profil
Informations personnelles :
Nom : Homme Christian Havard
Localisation : Belgique

Informations professionnelles :
Activité : Développeur informatique
Secteur : Conseil

Informations forums :
Inscription : mai 2011
Messages : 100
Points : 139
Points : 139
Bonjour

Tel quel, ton code devrait fonctionner. J'ai l'impression que ton problème vient
de l'encodage du fichier source.

Pour en être convaincu, essaie de faire si tu n'a pas str, ce n'est pas bon car, en python 3, tu ne peux mêler allègrement les type str et byte.

Voici quelquesconseils

Utilise un édieur qui sauvegarde nativement en utf-8
Commence tous tes codes par
Code :
1
2
3
 
#!/usr/bin/python
# -*- coding: utf-8 -*-
Quand tu poste du code, utilise la balise CODE, cela facilite la tâche de ceux
qui veulent t'aider.
En espérant t'avoir été utile
chticricri est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/12/2012, 16h11   #13
chticricri
Membre habitué
 
Homme Christian Havard
Développeur informatique
Inscription : mai 2011
Messages : 100
Détails du profil
Informations personnelles :
Nom : Homme Christian Havard
Localisation : Belgique

Informations professionnelles :
Activité : Développeur informatique
Secteur : Conseil

Informations forums :
Inscription : mai 2011
Messages : 100
Points : 139
Points : 139
Oups, dans le dernier exemple, j'ai malencontreusement inséré une ligne blanche.
Bien entendu, pour que cela fonctionne, il ne s la mettre
chticricri est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/12/2012, 10h44   #14
piloubu
Invité de passage
 
Homme
Inscription : février 2012
Messages : 10
Détails du profil
Informations personnelles :
Sexe : Homme

Informations forums :
Inscription : février 2012
Messages : 10
Points : 2
Points : 2
Tout fonctionne comme je voulais maintenant!!

Merci de vos nombreux conseils et coups de main et bonne continuation.
piloubu est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 02h49.


 
 
 
 
Partenaires

Hébergement Web