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.