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 15/11/2012, 12h05   #1
KR_Prog
Invité de passage
 
Inscription : avril 2010
Messages : 19
Détails du profil
Informations forums :
Inscription : avril 2010
Messages : 19
Points : 0
Points : 0
Par défaut Problème d'encodage utf-8/iso-8859-15

Bonjour,
J'ai un problème d'encodage (Python 2.6.6): j'ai un fichier texte où les données sont enregistrées en iso-8859-15 (sous windows) contenant une unique ligne :
Mon script est sous Linux :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
 
import codecs
 
if __name__ == '__main__':
	fichierTextWin = codecs.open('fichierTextWin.txt', 'r', 'iso-8859-15')
	lignes = fichierTextWin.readlines()
	print(lignes)
	for ligne in lignes:
		print ligne
		if '\xe9\n' == ligne:
			print("1 - ça marche")
		else:
			print("1 - ça ne marche pas")
		if 'é' == ligne:
			print("2 - ça marche")
		else:
			print("2 - ça ne marche pas")
		if u'é' == ligne:
			print("3 - ça marche")
		else:
			print("3 - ça ne marche pas")
et ça donne
Code :
1
2
3
4
5
6
7
8
9
[u'\xe9\r\n']
 
test_UTF-8_Linux.py:16: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
  if '\xe9\n' == ligne:
1 - ça ne marche pas
test_UTF-8_Linux.py:20: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
  if 'é' == ligne:
2 - ça ne marche pas
3 - ça ne marche pas
J'ai essayé dans l'autre sens: en enregistrant le fichier texte en utf-8 cette fois ci et là:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
import codecs
 
if __name__ == '__main__':
	fichierTextWin = codecs.open('fichierTextWin.txt', 'r', 'utf-8')
	lignes = fichierTextWin.readlines()
	print(lignes)
	for ligne in lignes:
		print ligne
		if u'\xe9\n' == ligne:
			print("1 - ça marche")
		else:
			print("1 - ça ne marche pas")
		if u'é' == ligne:
			print("2 - ça marche")
		else:
			print("2 - ça ne marche pas")
ça donne
Code :
1
2
1 - ça marche
2 - ça ne marche pas
Comment faire pour faire une conversion correcte sans avoir à écrire d'hexa ?
Merci d'avance !!
KR_Prog est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/11/2012, 18h27   #2
tyrtamos
Expert Confirmé
 
Avatar de tyrtamos
 
Inscription : décembre 2007
Messages : 1 774
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : décembre 2007
Messages : 1 774
Points : 3 043
Points : 3 043
Bonjour,

Quelques règles simples vont te permettre de sortir de ton problème.

1- la ligne du haut de la page de code "# -*- coding: iso-8859-15 -*-" dit à l'interpréteur Python comment sont encodées les chaines de caractères "codées en dur" dans la page (genre x = "é"). Cela ne veut absolument pas dire que Python devra travailler en "iso-8859-15"! Et quand on écrit x = u"é", Python convertit en unicode le "é" de la page, initialement en "iso-8859-15".

NB: si on met une telle ligne en haut de page, il est impératif que l'éditeur de texte utilisé édite et enregistre avec cet encodage, sinon, ça donne n'importe quoi. En cas de doute, il est intéressant de vérifier directement le fichier avec un éditeur hexa.

2- Avec Python 2.x, il faut travailler le plus possible en unicode, c'est à dire convertir le plus vite possible les données qui rentrent, et le plus tard possible le données qui sortent. Pour les données à échanger avec le disque, le module 'codecs' est très bon. Avec les autres entrées-sorties, il faut utiliser x.decode('iso-8859-15') pour convertir en unicode un 'x' initialement en 'iso-8859-15', et x.encode('iso-8859-15') pour convertir en 'iso-8859-15' un 'x' initialement en unicode.

Voilà des exemples concrets:

- créer un fichier texte comportant un "é" + fin de ligne, encodé 'iso-8859-15':

Code :
1
2
3
4
5
6
import codecs
 
nf = "test.txt"
x = u"é" # x est en unicode
with codecs.open(nf, 'w', 'iso-8859-15') as f:
    f.write(x + "\n")
- lire le contenu de ce fichier:

Code :
1
2
3
4
5
6
with codecs.open(nf, 'r', 'iso-8859-15') as f:
    ch = f.readline().rstrip() # rstrip supprime la fin de ligne
    # ch est en unicode
 
print ch, ch==u"é"
é True
3- ne pas oublier que la console d'affichage a elle aussi un encodage: il faut quelquefois convertir le chaine pour qu'elle s'affiche correctement. Cependant, de plus en plus acceptent l'affichage correct des chaines en unicode.
__________________
Ne rien ranger permet d'observer la loi universelle d'entropie: l'inévitable convergence vers le chaos...
Mes recettes python: http://www.jpvweb.com
tyrtamos est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 16/11/2012, 00h07   #3
alexdevl
Membre confirmé
 
Avatar de alexdevl
 
Inscription : avril 2007
Messages : 239
Détails du profil
Informations personnelles :
Âge : 44
Localisation : France, Loire (Rhône Alpes)

Informations forums :
Inscription : avril 2007
Messages : 239
Points : 275
Points : 275
Tyrtamos, je lis toujours tes postes sur l'encodage et celui-ci vient m'éclairer.
Il est vrai que je me demandais de quel encodage était question cette ligne :
"# -*- coding: iso-8859-15 -*-".
Dans mon esprit cela était flou entre les sorties fichiers, les variables texte, le codage du script dans l'éditeur.

Donc merci

Alex
alexdevl est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 00h14.


 
 
 
 
Partenaires

Hébergement Web