UnicodeDecodeError: codec 'ascii' không thể giải mã byte 0xef ở vị trí 1


106

Tôi đang gặp một số sự cố khi cố gắng mã hóa một chuỗi thành UTF-8. Tôi đã thử nhiều thứ, bao gồm cả việc sử dụng string.encode('utf-8')unicode(string), nhưng tôi gặp lỗi:

UnicodeDecodeError: codec 'ascii' không thể giải mã byte 0xef ở vị trí 1: thứ tự không trong phạm vi (128)

Đây là chuỗi của tôi:

(。・ω・。)ノ

Tôi không hiểu chuyện gì đang xảy ra, có ý kiến ​​gì không?

Chỉnh sửa: Vấn đề là in chuỗi như nó không hiển thị đúng. Ngoài ra, lỗi này khi tôi cố gắng chuyển đổi nó:

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)

Nó chỉ là một chuỗi được chèn thông thường. Điều tương tự cũng xảy ra khi tôi thử in nó.
Markum

Tôi gặp điều tương tự khi cài đặt pip và sửa nó từ đây: [cài đặt một số cấp độ] [1] [1]: stackoverflow.com/questions/17931726/…
BollMose

Câu trả lời:


70

Điều này liên quan đến việc mã hóa thiết bị đầu cuối của bạn không được đặt thành UTF-8. Đây là thiết bị đầu cuối của tôi

$ 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
(。・ω・。)ノ
>>> 

Trên thiết bị đầu cuối của tôi, ví dụ hoạt động với điều trên, nhưng nếu tôi thoát khỏi LANGcài đặt thì nó sẽ không hoạt động

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

Tham khảo tài liệu cho biến thể linux của bạn để khám phá cách thực hiện thay đổi này vĩnh viễn.


1
Thiếu ngôn ngữ cũng có thể là một lý do. Để cài đặt chúng, hãy chạy sudo apt-get install language-pack-dehoặc sudo locale-gen de_DE.UTF-8(đối với ngôn ngữ tiếng Đức).
Không phải

Đối với tôi, biến môi trường bị thiếu là LC_ALL, và giá trị đơn giản nhất có thể khắc phục nó làC.UTF-8
Robin Winslow

24

thử:

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

biên tập:

'(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'.decode('utf-8')cho u'(\uff61\uff65\u03c9\uff65\uff61)\uff89', đó là chính xác.

vì vậy, vấn đề của bạn phải nằm ở một nơi nào đó, có thể nếu bạn cố gắng làm điều gì đó với nó thì có một chuyển đổi ngầm đang diễn ra (có thể là in, ghi vào luồng ...)

để nói thêm, chúng tôi sẽ cần xem một số mã.


Cả hai đều trở lạiUnicodeEncodeError: 'charmap' codec can't encode characters in position 1-5: character maps to <undefined>
Markum

'(\xef\xbd\xa1\xef\xbd\xa5\xcf\x89\xef\xbd\xa5\xef\xbd\xa1)\xef\xbe\x89'
Markum

1
Tất cả những gì tôi đang cố gắng làm là in chuỗi gốc ở định dạng ban đầu của nó, nhưng tôi nhận được (´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë.
Markum

4
những stringlà utf8 mã hóa. nếu bạn in nó, nó chỉ ghi các byte vào luồng đầu ra và nếu thiết bị đầu cuối của bạn không hiểu nó là utf8 thì bạn sẽ có rác. với việc decodebạn chuyển đổi nó thành unicode, sau đó bạn có thể chuyển encodenó sang một bảng mã mà thiết bị đầu cuối của bạn hiểu được.
mata

21

+1 của tôi cho nhận xét của mata tại https://stackoverflow.com/a/10561979/1346705 và cho phần trình diễn của Nick Craig-Wood. Bạn đã giải mã chuỗi một cách chính xác. Vấn đề là với printlệnh vì nó chuyển đổi chuỗi Unicode sang bảng mã hóa bảng điều khiển và bảng điều khiển không có khả năng hiển thị chuỗi. Cố gắng ghi chuỗi vào một tệp và xem kết quả bằng một số trình soạn thảo phù hợp hỗ trợ 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()

Sau đó, bạn sẽ thấy (。・ω・。)ノ.


10

Nếu bạn đang làm việc trên một máy chủ từ xa , hãy xem /etc/ssh/ssh_configtrên PC cục bộ của bạn .

Khi tệp này chứa một dòng:

SendEnv LANG LC_*

bình luận nó ra bằng cách thêm #ở đầu dòng. Nó sẽ giúp.

Với dòng này, sshgửi các biến môi trường liên quan đến ngôn ngữ của PC của bạn đến máy chủ từ xa . Nó gây ra rất nhiều vấn đề.


Cảm ơn! Những điều này đã giải quyết được vấn đề mà tôi đã cài đặt các gói pip có khả năng nghe được và không hoạt động
Maritza Esparza

10

Hãy thử đặt mã hóa mặc định của hệ thống như utf-8ở đầu tập lệnh, để tất cả các chuỗi được mã hóa bằng cách sử dụng đó.

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

tại sao chúng ta cần tải lại trong trường hợp này?
falldog

Điều này không hoạt động trong Python 3 như được giải thích ở đây . Đối với tôi, câu trả lời của Tsutomu dưới đây đã làm được điều đó.
Piyush Goel

5

Bạn có thể sử dụng đoạn mã dưới đây ở đầu tập lệnh của mình như Andrei Krasutski đã đề xuất.

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

Nhưng tôi sẽ đề nghị bạn thêm # -*- coding: utf-8 -*dòng ở đầu tập lệnh.

Việc bỏ qua nó sẽ gây ra lỗi bên dưới trong trường hợp của tôi khi tôi cố gắng thực thi 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

Sau đây là đoạn mã có trong basic.pyđó có lỗi ở trên.

mã có lỗi

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)

Sau đó, tôi thêm # -*- coding: utf-8 -*-dòng ở trên cùng và thực thi. Nó đã làm việc.

mã không có lỗi

# -*- 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)

Cảm ơn.


1
Sử dụng #coding: utf-8hơn là # -*- coding: utf-8 -*- điều này dễ nhớ hơn. Hoạt động hiệu quả với Python PEP 263 - Định nghĩa mã hóa mã nguồn Python .
Andrei Krasutski

Cám ơn vì sự gợi ý. Sẽ thử ở cuối của tôi và cập nhật nó trong câu trả lời.
hygull

4

Không có vấn đề với thiết bị đầu cuối của tôi. Các câu trả lời trên đã giúp tôi tìm đúng hướng nhưng nó không hiệu quả với tôi cho đến khi tôi thêm 'ignore':

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

Như được chỉ ra trong nhận xét dưới đây, điều này có thể dẫn đến kết quả không mong muốn. OTOH nó cũng có thể thực hiện thủ thuật đủ tốt để mọi thứ hoạt động và bạn không quan tâm đến việc mất một số ký tự.


2
Điều này là sai, bạn đang buộc hàm lambda mã hóa của mình bỏ qua chính mã hóa, điều này có nghĩa là bạn đang mất ký tự.
Maximiliano Rios

2
Điều này đã giải quyết vấn đề của tôi, nơi tôi không biết mã hóa ban đầu và tôi không quan tâm đến việc mất một số ký tự.
Edhowler

2

điều này hoạt động cho ubuntu 15.10:

sudo locale-gen "en_US.UTF-8"
sudo dpkg-reconfigure locales

1

Có vẻ như chuỗi của bạn đã được mã hóa utf-8, vậy vấn đề chính xác là gì? Hay bạn đang cố gắng làm gì ở đây ..?

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'

In chuỗi gốc như đã cho (´¢í´¢Ñ¤ë´¢Ñ´¢í)´¥ë, tôi muốn nó mã hóa đúng cách.
Markum

1

Trong trường hợp của tôi, nguyên nhân là do tệp Unicode của tôi được lưu bằng "BOM". Để giải quyết vấn đề này, tôi đã bẻ khóa mở tệp bằng BBEdit và chọn "Lưu dưới dạng ..." để mã hóa "Unicode (UTF-8)" chứ không phải những gì nó đi kèm với "Unicode (UTF-8, với BOM) "


0

Tôi đã gặp cùng một loại lỗi và tôi thấy rằng bảng điều khiển không có khả năng hiển thị chuỗi bằng ngôn ngữ khác. Do đó, tôi đã thực hiện các thay đổi mã dưới đây để đặt default_charset là 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, nó thường là BOM đối với tôi

vi tập tin, sử dụng

:set nobomb

và lưu nó. Điều đó gần như luôn khắc phục được nó trong trường hợp của tôi


-1

Tôi đã gặp lỗi tương tự, với các URL chứa ký tự không phải ascii (byte có giá trị> 128)

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

Làm việc cho tôi, trong Python 2.7, tôi cho rằng bài tập này đã thay đổi 'một cái gì đó' trong strbiểu diễn bên trong - tức là, nó buộc giải mã đúng chuỗi byte được hỗ trợ urlvà cuối cùng đặt chuỗi thành utf-8 str với tất cả phép thuật trong đúng địa chỉ. Unicode trong Python là ma thuật đen đối với tôi. Hy vọng hữu ích


-2

tôi giải quyết vấn đề đó bằng cách thay đổi trong tệp settings.py bằng 'ENGINE': 'django.db.backends.mysql', không sử dụng 'ENGINE': 'mysql.connector.django',


@rayryeng Bạn có thể giải thích lý do chỉnh sửa của mình không? Nó dường như thay đổi hoàn toàn ý nghĩa của những gì OP đã viết, từ đề xuất một cài đặt cụ thể sang đề xuất chống lại nó.
không ai

@AndrewMedico - Tôi xin lỗi. Tôi thấy rằng bài đăng này rất giống với một bài khác nên tôi tin rằng chúng giống nhau. Tôi sẽ hoàn nguyên trở lại.
rayryeng

-2

Chỉ cần chuyển đổi văn bản một cách rõ ràng thành chuỗi bằng cách sử dụng str(). Đã làm cho tôi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.