Python3: UnicodeEncodeError: кодек «ascii» не может кодировать символ «\ xfc»

Я пытаюсь запустить очень простой пример на OSX с python 3.5.1, но я действительно застрял. Прочитал так много статей, посвященных подобным проблемам, но я не могу решить это самостоятельно. Есть ли у вас какие-либо подсказки, как решить эту проблему?

Я хотел бы иметь правильный закодированный вывод latin-1, как определено в mylist, без каких-либо ошибок.

Мой код:

# coding=<latin-1>

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

Ошибка:

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)

Как я могу исправить ошибку, но все еще получаю что-то не так с stdout (print):

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

Что я получаю на выходе:

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

Что показывает мне «локаль»:

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=

Что -> 'python3' показывает мне:

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'

person Hans Bondoka    schedule 10.08.2016    source источник
comment
Отлично работает на моей версии Windows python 3.4: mylist = [u'Glück', u'Spaß', u'Ähre',] for w в mylist: print(w) output: Glück Spaß Ähre, так что здесь нет проблем. Обратите внимание, что если вы используете encode, вы получаете тип bytes, а не тот, который вам нужен.   -  person Jean-François Fabre    schedule 10.08.2016


Ответы (3)


Удалите символы < и >:

# coding=latin-1

Эти символы часто используются в примерах, чтобы указать, куда идет имя кодировки, но буквальные символы < и > не должны включаться в ваш файл.

Чтобы это работало, ваш файл должен быть закодирован с использованием latin-1. Если ваш файл на самом деле закодирован с использованием utf-8, строка кодировки должна быть

# coding=utf-8

Например, когда я запускаю этот скрипт (сохраненный в виде файла с кодировкой latin-1):

# coding=latin-1

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

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

Я получаю этот вывод (без ошибок):

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

Этот вывод выглядит правильным. Например, латинская кодировка ü '\xfc'.

Я использовал свой редактор, чтобы сохранить файл с кодировкой latin-1. Содержимое файла в шестнадцатеричном формате:

$ 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

Обратите внимание, что первый байт (представленный в шестнадцатеричном формате) в третьей строке (то есть символ в позиции 0x20) равен fc. Это латинская кодировка ü. Если файл был закодирован с использованием utf-8, символ ü будет представлен двумя байтами, c3 bc.

person Warren Weckesser    schedule 10.08.2016
comment
Спасибо за подробное объяснение! - person Hans Bondoka; 11.08.2016

Попробуйте запустить скрипт с явно определенной переменной окружения PYTHONIOENCODING:

PYTHONIOENCODING=utf-8 python3 script.py
person markhor    schedule 19.12.2016
comment
Классный пример, тот факт, что он работает и отличается от других решений этой проблемы, делает его стоящим. - person Alfredo Gallegos; 01.08.2019

Если вы столкнулись с этой проблемой при чтении/записи файла, попробуйте это

import codecs

# File read 
with codecs.open(filename, 'r', encoding='utf8') as f:
    text = f.read()

# File write
with codecs.open(filename, 'w', encoding='utf8') as f:
    f.write(text)
person shivampip    schedule 07.11.2020