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)

Це просто нормально вставлена ​​рядок. Те саме відбувається, коли я просто намагаюся надрукувати його.
— Маркум

Я зустрічаю те ж саме , коли пункт встановити і зафіксувати його тут: [встановити деякі 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ви перетворите його на unicode, тоді ви зможете encodeце знову до кодування, яке ваш термінал розуміє.
— мата

21

Мій коментар від +1 до Mata на 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 і бродячим
— Maritza Esparza

10

Спробуйте встановити системне кодування за замовчуванням як utf-8на початку сценарію, щоб усі рядки були закодовані за допомогою цього.

# coding: utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

навіщо нам потрібно перезавантажити в цьому випадку?
— падіннядог

Це не працює в 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)

Дякую.


1
Використовувати, #coding: utf-8а не # -*- coding: utf-8 -*- це легше запам'ятати. Працює з коробки за допомогою Python PEP 263 - Визначення кодувань вихідного коду Python .
— Андрій Красуцький

Дякую за пропозицію. Спробую в моєму кінці та оновіть у відповіді.
— hygull

4

Немає проблем з моїм терміналом. Наведені вище відповіді допомогли мені шукати правильні напрямки, але це не спрацювало для мене, поки я не додав 'ignore':

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

Як зазначено в коментарі нижче, це може призвести до небажаних результатів. ОТО також може просто зробити трюк досить добре, щоб налагодити роботу, і вам не байдуже втрачати деяких персонажів.


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)" "


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

БОМ, це так часто для мене БОМ

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',


@rayryeng Чи можете ви пояснити причину редагування? Схоже, цілком змінюється значення того, що написала ОП, від рекомендування конкретної установки до рекомендації проти неї.
— ніхто

@AndrewMedico - Мої вибачення. Я бачив, що ця публікація дуже схожа на іншу, тому я вважав, що вони однакові. Я поверну назад.
— rayryeng

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