Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[Wilk ?] divers pb utf-8

6 réponses
Avatar
Michel Claveau - abstraction méta-galactique non triviale en fuite perpétuelle.
Bonjour !


Mon cher Wilk, depuis que j'ai suivi ta suggestion d'encoder en utf-8 les
scripts, j'ai des déboires tout partout...

Ah, Python et les encodages, ce n'est quand même pas simple.




1) écrire dans un fichier en utf-8 ?

Pourquoi le script suivant ne marche t'il pas ?

# -*- coding: utf-8 -*-

b=u"azérty"
f=open('temp.txt','wb')
f.write(b) #ici, erreur
f.close()

L'erreur :
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in
position 2: ordinal not in range(128)

Comment écrire un fichier en utf-8 ?



2) comment connaître l'encodage par défaut d'un script ? ou d'un module ?
Sachant que :
- j'ai des scripts qui arrivent de diverse manières (fichiers, TCP/IP,
pipes, services)
- en unicode, lorsque l'encodage d'un fichier n'est pas précisé, il est
supposé être en utf-8 ; mais les fichiers ASCII ou ANSI (cp1252) n'ont
aucune indication ; d'où confusion possible.



3) il y a des différences, entre :
u"azerty"
unicode("azerty")
Mais, lesquelles ? A priori, u"azerty" semble équivalent à
unicode("azerty","utf-8"), mais je ne suis pas sûr.

6 réponses

Avatar
Yermat
Michel Claveau - abstraction méta-galactique non triviale en fuite
perpétuelle. wrote:
Bonjour !


Mon cher Wilk, depuis que j'ai suivi ta suggestion d'encoder en utf-8 les
scripts, j'ai des déboires tout partout...

Ah, Python et les encodages, ce n'est quand même pas simple.




1) écrire dans un fichier en utf-8 ?
[...]
Comment écrire un fichier en utf-8 ?


Utilise open du module codecs :
http://docs.python.org/lib/module-codecs.html


2)[...]


Avatar
Wilk
"Michel Claveau - abstraction méta-galactique non triviale en fuite perpétuelle." writes:

Bonjour !


Mon cher Wilk, depuis que j'ai suivi ta suggestion d'encoder en utf-8 les
scripts, j'ai des déboires tout partout...

Ah, Python et les encodages, ce n'est quand même pas simple.



Quand je pense à l'Apple ][+ où les accents et les minuscules
n'existaient pas ! C'était le bon temps !




1) écrire dans un fichier en utf-8 ?

Pourquoi le script suivant ne marche t'il pas ?

# -*- coding: utf-8 -*-

b=u"azérty"
f=open('temp.txt','wb')
f.write(b) #ici, erreur
f.close()

L'erreur :
UnicodeEncodeError: 'ascii' codec can't encode character u'xe9' in
position 2: ordinal not in range(128)


Ton fichier source est peut-être bien encodé en utf-8 (tu n'as pas
d'erreur de syntaxe), mais c'est ta sortie qui ne l'est pas (open)


Comment écrire un fichier en utf-8 ?



2) comment connaître l'encodage par défaut d'un script ? ou d'un module ?
Sachant que :
- j'ai des scripts qui arrivent de diverse manières (fichiers, TCP/IP,
pipes, services)
- en unicode, lorsque l'encodage d'un fichier n'est pas précisé, il est
supposé être en utf-8 ; mais les fichiers ASCII ou ANSI (cp1252) n'ont
aucune indication ; d'où confusion possible.


C'est bien pour ça qu'il a été instauré la balise "-*- encoding..." !
Sinon c'est à ton éditeur de texte de trouver plus ou moins tout seul
l'encodage du fichier.




3) il y a des différences, entre :
u"azerty"
unicode("azerty")


Ce sont tous les deux des chaines en unicode, mais pas forcément avec le
même encodage, ça dépend de ton éditeur...

Mais, lesquelles ? A priori, u"azerty" semble équivalent à
unicode("azerty","utf-8"), mais je ne suis pas sûr.


Ca va dépendre de ton éditeur de texte.

Par ex chez moi l'interpréteur est en iso-8859-1 et l'encodage par
défaut est ascii :
u"mémé" == unicode("mémé")
Traceback (most recent call last):



File "<stdin>", line 1, in ?
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 1: ordinal not in range(128)
type(u"mémé")
<type 'unicode'>



u"mémé" == unicode("mémé","utf-8")
Traceback (most recent call last):



File "<stdin>", line 1, in ?
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 1-3: invalid data
u"mémé" == unicode("mémé","iso-8859-1")
True




--
William - http://flibuste.net



Avatar
Michel Claveau - abstraction méta-galactique non triviale en fuite perpétuelle.
Bonjour !

Merci pour cette solution ; ça fonctionne.

Sauf que j'ai un message que je n'avais jamais eu :
"Unexpected Python Error: exceptions.SystemError: compile_node:
unexpected node type"
lorsque j'appelle mon script depuis Internet-Explorer/javascript, alors que
je n'ai pas de message, lorsque je le lance directement. Mais, pour ce
point, je vais chercher calmement, en fin d'après-midi.

@-salutations
--
Michel Claveau
Avatar
Sylvain Thenault
On Fri, 07 Jan 2005 09:48:16 +0100, Michel Claveau - abstraction
méta-galactique non triviale en fuite perpétuelle. wrote:

Bonjour !


Mon cher Wilk, depuis que j'ai suivi ta suggestion d'encoder en utf-8 les
scripts, j'ai des déboires tout partout...

Ah, Python et les encodages, ce n'est quand même pas simple.


c'est pas spécifique à python... Le truc c'est surtout que python
supporte l'unicode, ce qui est loin d'être le cas de la majorité des
langages.
Ce qu'il faut bien comprendre, c'est qu'Unicode est une représentation
interne des chaines de caractères permettant de représenter tous les
caractères qu'on trouve dans le monde et ailleurs. Pour afficher une
chaine unicode, ou encore pour l'écrire dans un fichier, il est
nécessaire de l'encoder (i.e. récupérer un tableau d'octets) en
utilisant un encodage donné (UTF-8, Latin1...).

De manière plus générale, les entrées / sorties d'un programme
utilisent des chaines encodés. Ensuite, le programme lui-même va en
interne utiliser soit ces chaines encodés, sans transformation, soit des
chaines unicode (généralement quand on a besoin de manipuler différents
encodages, mais pas forcément :à terme, le type string de python va
surement disparaitre pour n'avoir que de l'unicode).

1) écrire dans un fichier en utf-8 ?

Pourquoi le script suivant ne marche t'il pas ?

# -*- coding: utf-8 -*-

b=u"azérty"
f=open('temp.txt','wb')
f.write(b) #ici, erreur
f.close()

L'erreur :
UnicodeEncodeError: 'ascii' codec can't encode character u'xe9' in
position 2: ordinal not in range(128)


Ici tu a "b" qui référence une chaine unicode, que tu veux écrire dans
un fichier. Comme je l'ai dit plus haut, on ne peut pas écrire une chaine
unicode dans un fichier, il faut d'abord l'encoder. Pour simplifier les
choses, python essaie de t'aider en encodant automatiquement les chaines
unicode dans la plupart des fonctions/méthodes attendant une chaine
encodée en argument. Le problème (pour les non anglophones), c'est que
pour cela il utilise l'encodage par défaut qui est ici l'ascii. Hors
l'ascii ne connait pas le caractère 'é', donc il se plante en te disant
qu'il est incapable d'encoder ce caractère.

(Note: il est possible de changer cet encodage par défaut mais ce n'est
pas recommandé)

Comment écrire un fichier en utf-8 ?


f.write(b.encode('UTF-8')

2) comment connaître l'encodage par défaut d'un script ? ou d'un
module ? Sachant que :
- j'ai des scripts qui arrivent de diverse manières (fichiers,
TCP/IP,
pipes, services)
- en unicode, lorsque l'encodage d'un fichier n'est pas précisé,
il est
supposé être en utf-8 ; mais les fichiers ASCII ou ANSI (cp1252) n'ont
aucune indication ; d'où confusion possible.


c'est un problème: par défaut on ne peut pas connaitre l'encodage d'un
fichier texte. Soit il faut que le standard utilisé permette de le
définir en début de fichier (comme un code source python ou un fichier
xml par exemple), soit il faut appliquer des heuristiques qui peuvent
éventuellement permettre de détecter l'encodage utilisé.
Je ne sais pas si je répond vraiment à ta question ici...

3) il y a des différences, entre :
u"azerty"
unicode("azerty")
Mais, lesquelles ? A priori, u"azerty" semble équivalent à
unicode("azerty","utf-8"), mais je ne suis pas sûr.


unicode('azerty') == unicode('azerty', sys.getdefaultencoding())
u'azerty' == unicode('azerty', encodage de ton fichier source)

où l'encodage du fichier source est soit spécifié par une directive au
début du fichier (-*- coding: ... -*- par exemple), soit deviné en
fonction des propriétés du système de fichier et/ ou de la locale
utilisée (voir l'attribut "encoding" qu'on trouve sur les objets fichiers
à partir de python 2.3). Par exemple :

:syt$ LC_ALL=C python
Python 2.3.4 (#2, Sep 24 2004, 08:39:09)
[GCC 3.3.4 (Debian 1:3.3.4-12)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
import sys
sys.stdin.encoding
'ANSI_X3.4-1968'




:syt$ LC_ALL=fr_FR python
Python 2.3.4 (#2, Sep 24 2004, 08:39:09)
[GCC 3.3.4 (Debian 1:3.3.4-12)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
import sys
sys.stdin.encoding
'ISO-8859-1'





C'est plus clair maintenant ou j'ai complètement embrouillé tout le
monde ?

--
Sylvain Thénault LOGILAB, Paris (France).

http://www.logilab.com http://www.logilab.fr http://www.logilab.org



Avatar
Michel Claveau - abstraction méta-galactique non triviale en fuite perpétuelle.
Bonjour !

Le problème, ce n'est pas Unicode(*), mais le fait qu'il y a beaucoup de
flou dans les encodages, que les possibilités de visualisation ne sont pas
encore complètement disponibles, que les traitements ne suivent pas
toujours.

Quand à remplacer les string par des chaînes unicode, il y a encore du
chemin à faire...

Par exemple, avec Python, sous windows, as-tu essayé d'ouvrir un fichier
ASCII, dont le nom est en unicode ? Des fois ça marche, des fois ça plante.
Alors qu'un simple notepad ouvre les mêmes fichiers sans problèmes.

Et toujours ce flou dans la définition des encodages. Par exemple, on ne
peut pas savoir, a priori, si un fichier, ou un script, est encodé en
cp1252, en utf-8, en ASCII, etc.

Dans codecs, également, les constantes BOM_UTF32_BE et BOM_UTF32_LE sont
définies, mais pas les codecs qui vont avec (sauf si l'on a installé
IConvCodec, mais je n'ai trouvé qu'une version pour Python 2.3)

En plus, la console windows est incapable de visualiser de l'utf-8 ou de
l'utf-16.



Bref, le problème n'est pas spécifique à Python (évidemment), mais Python
n'est pas mieux placé que d'autres langages, sur ce point. Or, on est
tellement habitué à ce que Python fasse mieux que les autres, qu'on y prend
goût.


Bonne journée
--
Michel Claveau







(*) encore que cette norme n'est pas encore finalisée, qu'il y a beaucoup de
bagarre. Il n'y a qu'à voir les polémiques récentes sur le choix de codage
du phénicien.
Autre cas "polémique" : l'UTF-7 ; beaucoup font comme si c'était abandonné ;
peu l'implémentent ; et pourtant il est utilisé dans l'IMAP (messagerie).
Avatar
Eric Brunel
Michel Claveau - abstraction méta-galactique non triviale en fuite perpétuelle.
wrote:
[snip] on est
tellement habitué à ce que Python fasse mieux que les autres, qu'on y prend
goût.


Comme on dit sur c.l.py: +1 QOTW ;-)
--
- Eric Brunel <eric (underscore) brunel (at) despammed (dot) com> -
PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com