UnicodeEncodeError: кодек 'ascii' не може кодувати символ u '\ u2013' у позиції 3 2: порядковий номер не в діапазоні (128)


75

Я аналізую файл xsl за допомогою xlrd. Більшість речей працюють нормально. У мене є словник, де ключі - це рядки, а значення - це списки рядків. Усі ключі та значення є унікодом. Я можу надрукувати більшість ключів і значень str()методом. Але деякі значення мають символ Unicode - \u2013для чого я отримую вищезазначену помилку.

Я підозрюю, що це відбувається, оскільки це вбудований в unicode unicode, і інтерпретатор python не може його декодувати. То як я можу позбутися цієї помилки?

Заздалегідь спасибі.

Відповіді:


78

Ви також можете надрукувати об'єкти Unicode, вам не потрібно робити str () навколо нього.

Якщо припустити, що ви дійсно хочете str:

Коли ви виконуєте str (u '\ u2013'), ви намагаєтесь перетворити рядок Unicode у 8-розрядний рядок. Для цього вам потрібно використовувати кодування, зіставлення даних Unicode з 8-бітними даними. Що str () робить, це те, що використовує системне кодування за замовчуванням, яке під Python 2 є ASCII. ASCII містить лише 127 перших кодових точок Unicode, тобто від \ u0000 до \ u007F1. В результаті ви отримуєте вищезазначену помилку, кодек ASCII просто не знає, що це таке (довгий штрих, до речі).

Тому вам потрібно вказати, яке кодування ви хочете використовувати. Загальними є ISO-8859-1, найвідоміший як Latin-1, який містить 256 перших кодових точок; UTF-8, який може кодувати всі кодові точки за допомогою кодування змінної довжини, CP1252, який є загальним для Windows, та різних китайських та японських кодувань.

Ви використовуєте їх так:

u'\u2013'.encode('utf8')

Результатом є str, що містить послідовність байтів, яка є представленням uTF8 відповідного символу:

'\xe2\x80\x93'

І ви можете роздрукувати його:

>>> print '\xe2\x80\x93'

Це було дуже всебічно. Дякую. У мене було запитання - скажімо, Twitter-потік, ви б не знали кодування заздалегідь. Як би ти з цим впорався?
karthikr

@karthikr: Мені важко повірити, що Twitter не забезпечує кодування.
Леннарт Регебро

29

Ви також можете спробувати це, щоб отримати текст.

foo.encode('ascii', 'ignore')

1
Після багатьох пошукових запитів це виправило це для мене. Моє особливе використання було в друку через те, що і Windows, і Linux викликали цю помилку кодування.
ddisqq

Це призведе до втрати даних для будь-яких не-ascii, правильним методом є кодування з використанням правильного кодування.
Падрайк Каннінгем,

Це проігнорує символ, що не є ASCII. Ваша відповідь - просто ігнорувати проблему?
Джон Строуд,

Якщо ви не використовуєте символи не ASCII, тоді так.
Притеш Десай

Навіщо називати рядок "foo"?
ghosh

7

Оскільки тут str(u'\u2013')виникає помилка, використовуйте, isinstance(foo,basestring)щоб перевірити Unicode / рядок, якщо не базового рядка типу, перетворіть його в Unicode, а потім застосуйте encode

if isinstance(foo,basestring):
    foo.encode('utf8')
else:
    unicode(foo).encode('utf8')

далі читати


Навіщо називати рядок "foo"?
ghosh

5

У мене була та сама проблема. Для мене це прекрасно працює:

str(objdata).encode('utf-8')

2

У мене було саме це питання в недавньому проекті, який справді є болем у тилу. Нарешті я знайшов це тому, що Python, який ми використовували в Docker, має кодування "ansi_x3.4-1968" замість "utf-8". Отже, якщо хтось там, хто використовує Docker, і отримав цю помилку, виконавши ці дії, ви можете повністю вирішити вашу проблему.

  1. створити файл і назвати його default_locale в тому ж каталозі вашого Dockerfile, помістити в нього цей рядок,

    середовище = LANG = "es_ES.utf8", LC_ALL = "es_ES.UTF-8", LC_LANG = "es_ES.UTF-8"

  2. додайте їх у свій Dockerfile,

    ЗАПУСКАТИ apt-get clean && apt-get update && apt-get install -y locales

    ЗАПУСКАТИ локаль-gen en_CA.UTF-8

    КОПІЮВАТИ. / Default_locale / etc / default / locale

    ЗАПУСКАТИ chmod 0755 / etc / default / locale

    ENV LC_ALL = uk_CA.UTF-8

    ENV LANG = en_CA.UTF-8

    ENV LANGUAGE = en_CA.UTF-8

Це ретельно вирішило мою проблему, коли я знову створив і запустив свій Docker, сподіваюся, це вирішить і вашу проблему.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.