web-dev-qa-db-fra.com

Python3: UnicodeEncodeError: le codec 'ascii' ne peut pas coder le caractère '\ xfc'

J'essaie de lancer un exemple très simple sur OSX avec python 3.5.1 mais je suis vraiment bloqué. J'ai lu tellement d'articles qui traitent de problèmes similaires mais je ne peux pas résoudre ce problème par moi-même. Avez-vous des conseils sur la façon de résoudre ce problème?

Je voudrais avoir la sortie latin-1 encodée correcte telle que définie dans mylist sans aucune erreur.

Mon code:

# coding=<latin-1>

mylist = [u'Glück', u'Spaß', u'Ähre',]
print(mylist)

L'erreur:

Traceback (most recent call last):
File "/Users/abc/test.py", line 4, in <module>
print(mylist)
UnicodeEncodeError: 'ascii' codec can't encode character '\xfc' in position 4: ordinal not in range(128)

Comment je peux corriger l'erreur tout en obtenant un problème avec stdout (print):

mylist = [u'Glück', u'Spaß', u'Ähre',]
    for w in mylist:
        print(w.encode("latin-1"))

Ce que j'obtiens en sortie:

b'Gl\xfcck'
b'Spa\xdf'
b'\xc4hre'

Que "locale" me montre:

LANG="de_AT.UTF-8"
LC_COLLATE="de_AT.UTF-8"
LC_CTYPE="de_AT.UTF-8"
LC_MESSAGES="de_AT.UTF-8"
LC_MONETARY="de_AT.UTF-8"
LC_NUMERIC="de_AT.UTF-8"
LC_TIME="de_AT.UTF-8"
LC_ALL=

Ce que -> 'python3' me montre:

Python 3.5.1 (default, Jan 22 2016, 08:54:32) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.getdefaultencoding()
'utf-8'
11
Hans Bondoka

Supprimez les caractères < et >:

# coding=latin-1

Ces caractères sont souvent utilisés dans les exemples pour indiquer où va le nom de l'encodage, mais les caractères littéraux < et > ne doit pas être inclus dans votre fichier.

Pour que cela fonctionne, votre fichier doit être encodé en latin-1. Si votre fichier est réellement encodé en utilisant utf-8, la ligne d'encodage doit être

# coding=utf-8

Par exemple, lorsque j'exécute ce script (enregistré sous forme de fichier avec l'encodage latin-1):

# coding=latin-1

mylist = [u'Glück', u'Spaß', u'Ähre',]
print(mylist)

for w in mylist:
    print(w.encode("latin-1"))

J'obtiens cette sortie (sans erreur):

['Glück', 'Spaß', 'Ähre']
b'Gl\xfcck'
b'Spa\xdf'
b'\xc4hre'

Cette sortie semble correcte. Par exemple, le codage latin-1 de ü est '\xfc'.

J'ai utilisé mon éditeur pour enregistrer le fichier avec l'encodage latin-1. Le contenu du fichier en hexadécimal est:

$ hexdump -C  codec-question.py 
00000000  23 20 63 6f 64 69 6e 67  3d 6c 61 74 69 6e 2d 31  |# coding=latin-1|
00000010  0a 0a 6d 79 6c 69 73 74  20 3d 20 5b 75 27 47 6c  |..mylist = [u'Gl|
00000020  fc 63 6b 27 2c 20 75 27  53 70 61 df 27 2c 20 75  |.ck', u'Spa.', u|
00000030  27 c4 68 72 65 27 2c 5d  0a 70 72 69 6e 74 28 6d  |'.hre',].print(m|
00000040  79 6c 69 73 74 29 0a 0a  66 6f 72 20 77 20 69 6e  |ylist)..for w in|
00000050  20 6d 79 6c 69 73 74 3a  0a 20 20 20 20 70 72 69  | mylist:.    pri|
00000060  6e 74 28 77 2e 65 6e 63  6f 64 65 28 22 6c 61 74  |nt(w.encode("lat|
00000070  69 6e 2d 31 22 29 29 0a                           |in-1")).|
00000078

Notez que le premier octet (représenté en hexadécimal) dans la troisième ligne (c'est-à-dire le caractère à la position 0x20) est fc. C'est l'encodage latin-1 de ü. Si le fichier était codé en utilisant utf-8, le caractère ü serait représenté en utilisant deux octets, c3 bc.

6
Warren Weckesser

Essayez d'exécuter votre script avec la variable d'environnement PYTHONIOENCODING explicitement définie:

PYTHONIOENCODING=utf-8 python3 script.py
6
markhor