UnicodeDecodeError: кодек ascii не может декодировать байт 0xef в позиции 1

106

У меня возникают проблемы с кодированием строки в UTF-8. Я пробовал множество вещей, в том числе с помощью string.encode('utf-8')и unicode(string), но получаю сообщение об ошибке:

UnicodeDecodeError: кодек ascii не может декодировать байт 0xef в позиции 1: порядковый номер не в диапазоне (128)

Это моя строка:

(。・ω・。)ノ

Я не понимаю, что не так, есть идеи?

Изменить: проблема в том, что печать строки, как она есть, не отображается должным образом. Кроме того, эта ошибка, когда я пытаюсь ее преобразовать:

Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-5: ordinal not in range(128)
Маркум
источник
Это просто нормально вставленная строка. То же самое происходит, когда я просто пытаюсь распечатать его.
Маркум
Я встречаю то же самое при установке pip и исправляю это отсюда: [install some devel] [1] [1]: stackoverflow.com/questions/17931726/…
BollMose

Ответы:

70

Это связано с тем, что кодировка вашего терминала не установлена ​​в UTF-8. Вот мой терминал

$ echo $LANG
en_GB.UTF-8
$ python
Python 2.7.3 (default, Apr 20 2012, 22:39:59) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
(。・ω・。)ノ
>>> 

На моем терминале пример работает с приведенным выше, но если я избавлюсь от LANGнастройки, он не будет работать

$ unset LANG
$ python
Python 2.7.3 (default, Apr 20 2012, 22:39:59) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-5: ordinal not in range(128)
>>> 

Обратитесь к документации для своего варианта Linux, чтобы узнать, как сделать это изменение постоянным.

Ник Крейг-Вуд
источник
1
Отсутствие локаций также могло быть причиной. Для их установки запустите sudo apt-get install language-pack-deили sudo locale-gen de_DE.UTF-8(для немецких языков).
Не
Для меня отсутствует переменная среды LC_ALL, и самое простое значение, которое могло бы ее исправить,C.UTF-8
Робин Уинслоу,
24

пытаться:

string.decode('utf-8')  # or:
unicode(string, 'utf-8')

редактировать:

'(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'.decode('utf-8')дает u'(\uff61\uff65\u03c9\uff65\uff61)\uff89', что правильно.

поэтому ваша проблема должна быть в каком-то другом месте, возможно, если вы попытаетесь что-то с ней сделать, если происходит неявное преобразование (может быть печать, запись в поток ...)

чтобы сказать больше, нам понадобится код.

мата
источник
Оба возвращаютсяUnicodeEncodeError: 'charmap' codec can't encode characters in position 1-5: character maps to <undefined>
Маркум
'(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
Маркум
1
Все, что я пытаюсь сделать, это распечатать исходную строку в исходном формате, но получаю (´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë.
Маркум
4
stringявляется utf8 кодировке. если вы его распечатаете, он просто отправит байты в выходной поток, и если ваш терминал не интерпретирует его как utf8, вы получите мусор. с decodeконвертированием его в юникод, то вы можете encodeснова кодированию ваш терминал понимает.
mata
21

Мой +1 к комментарию Маты на https://stackoverflow.com/a/10561979/1346705 и к демонстрации Ника Крейга-Вуда. Вы правильно расшифровали строку. Проблема заключается в printкоманде, поскольку она преобразует строку Unicode в кодировку консоли, а консоль не может отображать строку. Попробуйте записать строку в файл и посмотреть результат с помощью какого-нибудь приличного редактора, поддерживающего Unicode:

import codecs

s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
s1 = s.decode('utf-8')
f = codecs.open('out.txt', 'w', encoding='utf-8')
f.write(s1)
f.close()

Тогда вы увидите (。・ω・。)ノ.

перец
источник
10

Если вы работаете на удаленном хосте, посмотрите /etc/ssh/ssh_configна свой локальный компьютер.

Когда этот файл содержит строку:

SendEnv LANG LC_*

закомментируйте это, добавив #в начало строки. Это может помочь.

С помощью этой строки sshотправляет на удаленный хост переменные среды вашего ПК, связанные с языком . Это вызывает массу проблем.

Цутому
источник
Спасибо! Они решили проблему, связанную с установкой пакетов pip с помощью ansible и vagrant
Maritza Esparza
10

Попробуйте установить системную кодировку по умолчанию, как utf-8в начале скрипта, чтобы все строки кодировались с ее использованием.

# coding: utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
Андрей Красуцкий
источник
зачем нам в таком случае перезагрузка?
Falldog
Это не работает в Python 3, как описано здесь . Для меня ответ Цутому ниже помог.
Пиюш Гоэль
5

Как предложил Андрей Красуцкий, можно использовать приведенный ниже код в верхней части сценария .

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

Но я предлагаю вам также добавить # -*- coding: utf-8 -*строку в самом верху скрипта.

Пропуск этого вызывает ошибку ниже в моем случае, когда я пытаюсь выполнить basic.py.

$ python basic.py
  File "01_basic.py", line 14
SyntaxError: Non-ASCII character '\xd9' in file basic.py on line 14, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

Ниже приведен код, в basic.pyкотором возникает указанная выше ошибка.

код с ошибкой

from pylatex import Document, Section, Subsection, Command, Package
from pylatex.utils import italic, NoEscape

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

def fill_document(doc):
    with doc.create(Section('ِش سثؤفهخى')):
        doc.append('إخع ساخعمي شمصشغس سحثشن فاث فقعفا')
        doc.append(italic('فشمهؤ ؤخىفثىفس شقث شمسخ ىهؤث'))

        with doc.create(Subsection('آثص ٍعلاسثؤفهخى')):
            doc.append('بشةخعس ؤقشئغ ؤاشقشؤفثقس: $&#{}')


if __name__ == '__main__':
    # Basic document
    doc = Document('basic')
    fill_document(doc)

Затем я добавил # -*- coding: utf-8 -*-строку в самом верху и выполнил. Это сработало.

код без ошибок

# -*- coding: utf-8 -*-
from pylatex import Document, Section, Subsection, Command, Package
from pylatex.utils import italic, NoEscape

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

def fill_document(doc):
    with doc.create(Section('ِش سثؤفهخى')):
        doc.append('إخع ساخعمي شمصشغس سحثشن فاث فقعفا')
        doc.append(italic('فشمهؤ ؤخىفثىفس شقث شمسخ ىهؤث'))

        with doc.create(Subsection('آثص ٍعلاسثؤفهخى')):
            doc.append('بشةخعس ؤقشئغ ؤاشقشؤفثقس: $&#{}')


if __name__ == '__main__':
    # Basic document
    doc = Document('basic')
    fill_document(doc)

Спасибо.

Hygull
источник
1
Легче запомнить использование, #coding: utf-8а не # -*- coding: utf-8 -*-это. Готово к работе с Python PEP 263 - Определение кодировок исходного кода Python .
Андрей Красуцкий
Спасибо за предложение. Попробую на моем конце и обновлю его в ответе.
hygull
4

С моим терминалом проблем нет. Приведенные выше ответы помогли мне найти правильное направление, но у меня ничего не вышло, пока я не добавил 'ignore':

fix_encoding = lambda s: s.decode('utf8', 'ignore')

Как указано в комментарии ниже, это может привести к нежелательным результатам. OTOH, он также может достаточно хорошо справиться с задачей, чтобы все работало, и вас не волнует потеря некоторых персонажей.

kqw
источник
2
Это неправильно, вы заставляете лямбда-функцию кодирования игнорировать саму кодировку, что означает, что вы теряете символы.
Максимилиано Риос
2
Это решило мою проблему, когда я не знал исходную кодировку и не беспокоился о потере некоторых символов.
Edhowler
2

это работает для ubuntu 15.10:

sudo locale-gen "en_US.UTF-8"
sudo dpkg-reconfigure locales
белый глаз
источник
1

Похоже, ваша строка закодирована utf-8, так в чем именно проблема? Или что ты здесь делаешь ..?

Python 2.7.3 (default, Apr 20 2012, 22:39:59) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = '(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
>>> s1 = s.decode('utf-8')
>>> print s1
(。・ω・。)ノ
>>> s2 = u'(。・ω・。)ノ'
>>> s2 == s1
True
>>> s2
u'(\uff61\uff65\u03c9\uff65\uff61)\uff89'
слабак
источник
Печать исходной строки как есть (´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë, я хочу, чтобы она правильно кодировалась.
Маркум
1

В моем случае это было вызвано тем, что мой файл Unicode сохранялся с "BOM". Чтобы решить эту проблему, я взломал файл с помощью BBEdit и сделал «Сохранить как ...», выбрав для кодирования «Unicode (UTF-8)», а не то, с чем он был, «Unicode (UTF-8, с BOM)» "

пользователь336828
источник
0

Я получал ошибку того же типа и обнаружил, что консоль не может отображать строку на другом языке. Поэтому я внес следующие изменения кода, чтобы установить default_charset как UTF-8.

data_head = [('\x81\xa1\x8fo\x89\xef\x82\xa2\x95\xdb\x8f\xd8\x90\xa7\x93x\x81\xcb3\x8c\x8e\x8cp\x91\xb1\x92\x86(\x81\x86\x81\xde\x81\x85)\x81\xa1\x8f\x89\x89\xf1\x88\xc8\x8aO\x81A\x82\xa8\x8b\xe0\x82\xcc\x90S\x94z\x82\xcd\x88\xea\x90\xd8\x95s\x97v\x81\xa1\x83}\x83b\x83v\x82\xcc\x82\xa8\x8e\x8e\x82\xb5\x95\xdb\x8c\xaf\x82\xc5\x8fo\x89\xef\x82\xa2\x8am\x92\xe8\x81\xa1', 'shift_jis')]
default_charset = 'UTF-8' #can also try 'ascii' or other unicode type
print ''.join([ unicode(lin[0], lin[1] or default_charset) for lin in data_head ])
Азам Хан
источник
-1

BOM, это так часто для меня BOM

vi файл, используйте

:set nobomb

и сохраните его. Это почти всегда исправляет это в моем случае

Олли В
источник
-1

У меня была такая же ошибка с URL-адресами, содержащими символы, отличные от ascii (байты со значениями> 128)

url = url.decode('utf8').encode('utf-8')

Сработало для меня, в Python 2.7, я полагаю, это назначение изменило «что-то» во strвнутреннем представлении - то есть оно заставляет правильно декодировать поддерживаемую последовательность байтов urlи, наконец, помещает строку в utf-8 str со всей магией в в нужном месте. Unicode в Python для меня - черная магия. Надеюсь полезно

Фабиано Тарлао
источник
-2

Я решаю эту проблему, изменяя в файле settings.py с помощью 'ENGINE': 'django.db.backends.mysql', не используйте 'ENGINE': 'mysql.connector.django',

user3787102
источник
@rayryeng Не могли бы вы объяснить причину вашего редактирования? Похоже, что это полностью меняет смысл того, что написал OP, от рекомендации определенной настройки до рекомендации против нее.
никто
@AndrewMedico - Мои извинения. Я увидел, что этот пост очень похож на другой, поэтому я подумал, что они такие же. Я вернусь назад.
Rayryeng
-2

Просто преобразуйте текст в строку с помощью str(). Работал у меня.

Супратим Самантрай
источник