Cách khắc phục: Unicode UnicodeDecodeError: 'ascii' codec không thể giải mã byte byte


459
as3:~/ngokevin-site# nano content/blog/20140114_test-chinese.mkd
as3:~/ngokevin-site# wok
Traceback (most recent call last):
File "/usr/local/bin/wok", line 4, in
Engine()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 104, in init
self.load_pages()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 238, in load_pages
p = Page.from_file(os.path.join(root, f), self.options, self, renderer)
File "/usr/local/lib/python2.7/site-packages/wok/page.py", line 111, in from_file
page.meta['content'] = page.renderer.render(page.original)
File "/usr/local/lib/python2.7/site-packages/wok/renderers.py", line 46, in render
return markdown(plain, Markdown.plugins)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 419, in markdown
return md.convert(text)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 281, in convert
source = unicode(source)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 1: ordinal not in range(128). -- Note: Markdown only accepts unicode input!

Làm thế nào để khắc phục nó?

Trong một số ứng dụng blog tĩnh dựa trên python khác, bài viết tiếng Trung có thể được xuất bản thành công. Chẳng hạn như ứng dụng này: http://github.com/vrypan/bucket3 . Trong trang web của tôi http://bc3.brite.biz/ , bài viết tiếng Trung có thể được xuất bản thành công.


Câu trả lời:


569

tl; dr / sửa chữa nhanh

  • Không giải mã / mã hóa willy nilly
  • Đừng cho rằng chuỗi của bạn được mã hóa UTF-8
  • Cố gắng chuyển đổi chuỗi thành chuỗi Unicode càng sớm càng tốt trong mã của bạn
  • Khắc phục ngôn ngữ của bạn: Làm thế nào để giải quyết UnicodeDecodeError trong Python 3.6?
  • Đừng cố sử dụng reloadhack nhanh

Unicode Zen trong Python 2.x - Phiên bản dài

Không nhìn thấy nguồn, thật khó để biết nguyên nhân gốc rễ, vì vậy tôi sẽ phải nói chung.

UnicodeDecodeError: 'ascii' codec can't decode bytethường xảy ra khi bạn cố gắng chuyển đổi Python 2.x strcó chứa không phải ASCII thành chuỗi Unicode mà không chỉ định mã hóa của chuỗi gốc.

Tóm lại, chuỗi Unicode là một loại chuỗi Python hoàn toàn riêng biệt không chứa bất kỳ mã hóa nào. Họ chỉ giữ mã điểm Unicode và do đó có thể giữ bất kỳ điểm Unicode nào trên toàn bộ phổ. Các chuỗi chứa văn bản được mã hóa, beit UTF-8, UTF-16, ISO-8895-1, GBK, Big5, v.v. Các chuỗi được giải mã thành UnicodeUnicodes được mã hóa thành chuỗi . Các tệp và dữ liệu văn bản luôn được chuyển trong các chuỗi được mã hóa.

Các tác giả mô-đun Markdown có thể sử dụng unicode()(nơi ném ngoại lệ) làm cổng chất lượng cho phần còn lại của mã - nó sẽ chuyển đổi ASCII hoặc bọc lại các chuỗi Unicodes hiện có thành chuỗi Unicode mới. Các tác giả Markdown không thể biết mã hóa chuỗi đến, vì vậy sẽ dựa vào bạn để giải mã chuỗi thành chuỗi Unicode trước khi chuyển sang Markdown.

Chuỗi Unicode có thể được khai báo trong mã của bạn bằng cách sử dụng utiền tố cho chuỗi. Ví dụ

>>> my_u = u'my ünicôdé strįng'
>>> type(my_u)
<type 'unicode'>

Chuỗi Unicode cũng có thể đến từ tệp, cơ sở dữ liệu và mô-đun mạng. Khi điều này xảy ra, bạn không cần phải lo lắng về việc mã hóa.

Gotchas

Chuyển đổi từ strUnicode có thể xảy ra ngay cả khi bạn không gọi rõ ràng unicode().

Các tình huống sau đây gây ra UnicodeDecodeErrorngoại lệ:

# Explicit conversion without encoding
unicode('€')

# New style format string into Unicode string
# Python will try to convert value string to Unicode first
u"The currency is: {}".format('€')

# Old style format string into Unicode string
# Python will try to convert value string to Unicode first
u'The currency is: %s' % '€'

# Append string to Unicode
# Python will try to convert string to Unicode first
u'The currency is: ' + '€'         

Ví dụ

Trong sơ đồ sau, bạn có thể thấy từ caféđã được mã hóa theo mã hóa "UTF-8" hoặc "Cp1252" tùy thuộc vào loại thiết bị đầu cuối. Trong cả hai ví dụ, cafchỉ là ascii thông thường. Trong UTF-8, éđược mã hóa bằng hai byte. Trong "Cp1252", é là 0xE9 (cũng là giá trị điểm Unicode (không phải là ngẫu nhiên)). Chính xác decode()được gọi và chuyển đổi sang Unicode Unicode là thành công: Sơ đồ chuỗi được chuyển đổi thành chuỗi Unicode Python

Trong sơ đồ này, decode()được gọi với ascii(giống như gọi unicode()mà không có mã hóa). Vì ASCII không thể chứa byte lớn hơn 0x7F, điều này sẽ tạo ra một UnicodeDecodeErrorngoại lệ:

Sơ đồ chuỗi được chuyển đổi thành chuỗi Unicode Python với mã hóa sai

Sandwich Sandwich

Cách tốt nhất là tạo một bánh sandwich Unicode trong mã của bạn, nơi bạn giải mã tất cả dữ liệu đến thành chuỗi Unicode, làm việc với Unicodes, sau đó mã hóa thành strs trên đường ra. Điều này giúp bạn không phải lo lắng về việc mã hóa chuỗi ở giữa mã của bạn.

Nhập / Giải mã

Mã nguồn

Nếu bạn cần nướng non-ASCII vào mã nguồn của mình, chỉ cần tạo các chuỗi Unicode bằng cách thêm tiền tố vào chuỗi u. Ví dụ

u'Zürich'

Để cho phép Python giải mã mã nguồn của bạn, bạn sẽ cần thêm một tiêu đề mã hóa để khớp với mã hóa thực tế của tệp của bạn. Ví dụ: nếu tệp của bạn được mã hóa dưới dạng 'UTF-8', bạn sẽ sử dụng:

# encoding: utf-8

Điều này chỉ cần thiết khi bạn không có ASCII trong mã nguồn của mình .

Các tập tin

Thông thường dữ liệu không phải ASCII được nhận từ một tệp. Các iomô-đun cung cấp một TextWrapper rằng giải mã tập tin của bạn một cách nhanh chóng, sử dụng một định encoding. Bạn phải sử dụng mã hóa chính xác cho tệp - không thể dễ dàng đoán được. Ví dụ: đối với tệp UTF-8:

import io
with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file:
     my_unicode_string = my_file.read() 

my_unicode_stringsau đó sẽ thích hợp để chuyển đến Markdown. Nếu a UnicodeDecodeErrortừ read()dòng, thì có lẽ bạn đã sử dụng giá trị mã hóa sai.

Tệp CSV

Mô-đun CSV 2.7 2.7 không hỗ trợ các ký tự không phải ASCII. Tuy nhiên, sự giúp đỡ đã sẵn sàng với https://pypi.python.org/pypi/backports.csv .

Sử dụng nó như trên nhưng chuyển tập tin đã mở cho nó:

from backports import csv
import io
with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file:
    for row in csv.reader(my_file):
        yield row

Cơ sở dữ liệu

Hầu hết các trình điều khiển cơ sở dữ liệu Python có thể trả về dữ liệu bằng Unicode, nhưng thường yêu cầu một chút cấu hình. Luôn sử dụng chuỗi Unicode cho các truy vấn SQL.

MySQL

Trong chuỗi kết nối thêm:

charset='utf8',
use_unicode=True

Ví dụ

>>> db = MySQLdb.connect(host="localhost", user='root', passwd='passwd', db='sandbox', use_unicode=True, charset="utf8")
PostgreSQL

Thêm vào:

psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)

HTTP

Các trang web có thể được mã hóa trong bất kỳ mã hóa nào. Các Content-typetiêu đề phải chứa một charsetlĩnh vực để ám chỉ mã hóa. Nội dung sau đó có thể được giải mã thủ công theo giá trị này. Ngoài ra, Python-Request trả về Unicodes response.text.

Thủ công

Nếu bạn phải giải mã các chuỗi theo cách thủ công, bạn có thể chỉ cần thực hiện my_string.decode(encoding), encodingmã hóa phù hợp ở đâu. Các codec được hỗ trợ Python 2.x được đưa ra ở đây: Mã hóa tiêu chuẩn . Một lần nữa, nếu bạn nhận được UnicodeDecodeErrorthì có lẽ bạn đã mã hóa sai.

Thịt của bánh sandwich

Làm việc với Unicodes như bạn sẽ bình thường.

Đầu ra

xuất bản / in

printviết qua dòng stdout. Python cố gắng định cấu hình bộ mã hóa trên thiết bị xuất chuẩn để Unicodes được mã hóa thành mã hóa của bàn điều khiển. Ví dụ: nếu shell của Linux localeen_GB.UTF-8, đầu ra sẽ được mã hóa thành UTF-8. Trên Windows, bạn sẽ bị giới hạn ở trang mã 8 bit.

Một bảng điều khiển được cấu hình không chính xác, chẳng hạn như ngôn ngữ bị hỏng, có thể dẫn đến các lỗi in không mong muốn. PYTHONIOENCODINGbiến môi trường có thể buộc mã hóa cho thiết bị xuất chuẩn.

Các tập tin

Giống như đầu vào, io.opencó thể được sử dụng để chuyển đổi trong suốt Unicodes thành các chuỗi byte được mã hóa.

Cơ sở dữ liệu

Cấu hình tương tự để đọc sẽ cho phép Unicodes được viết trực tiếp.

Con trăn 3

Python 3 không có nhiều khả năng Unicode hơn Python 2.x, tuy nhiên nó hơi bị nhầm lẫn về chủ đề này. Ví dụ, thông thường strbây giờ là một chuỗi Unicode và strbây giờ là cũ bytes.

Mã hóa mặc định là UTF-8, vì vậy nếu bạn .decode()là một chuỗi byte mà không đưa ra mã hóa, Python 3 sử dụng mã hóa UTF-8. Điều này có thể khắc phục 50% các vấn đề Unicode của mọi người.

Hơn nữa, open()hoạt động ở chế độ văn bản theo mặc định, do đó trả về giải mã str(Unicode). Mã hóa được lấy từ ngôn ngữ của bạn, có xu hướng là UTF-8 trên các hệ thống Un * x hoặc trang mã 8 bit, chẳng hạn như windows-1251, trên các hộp Windows.

Tại sao bạn không nên sử dụng sys.setdefaultencoding('utf8')

Đó là một hack khó chịu (có một lý do bạn phải sử dụng reload) sẽ chỉ che giấu các vấn đề và cản trở việc di chuyển của bạn sang Python 3.x. Hiểu vấn đề, khắc phục nguyên nhân gốc và thưởng thức Unicode zen. Xem tại sao chúng ta KHÔNG nên sử dụng sys.setdefaultencoding ("utf-8") trong tập lệnh py? để biết thêm chi tiết


2
Đối với ai đó đang tìm kiếm câu trả lời Python 2, một TLDR hữu ích hơn: sử dụng io.openđể đọc / ghi tệp, sử dụng from __future__ import unicode_literals, định cấu hình các đầu vào / đầu ra dữ liệu khác (ví dụ: cơ sở dữ liệu) để sử dụng unicode.
idbrii

Làm thế nào để chúng tôi sửa chữa nó? lol đây không phải là vấn đề khi viết kịch bản - đó là từ việc cài đặt một
Matthew

@Matthew thử cài đặt PYTHONIOENCODING=utf-8. Nếu không khắc phục được, bạn cần liên hệ với tác giả của tập lệnh để sửa mã của họ.
Alastair McCormack

498

Cuối cùng tôi đã nhận được nó:

as3:/usr/local/lib/python2.7/site-packages# cat sitecustomize.py
# encoding=utf8  
import sys  

reload(sys)  
sys.setdefaultencoding('utf8')

Để tôi kiểm tra:

as3:~/ngokevin-site# python
Python 2.7.6 (default, Dec  6 2013, 14:49:02)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> reload(sys)
<module 'sys' (built-in)>
>>> sys.getdefaultencoding()
'utf8'
>>>

Ở trên cho thấy mã hóa mặc định của python là utf8. Sau đó, lỗi không còn nữa.


7
Tôi thử điều này nhưng nó không thể thay đổi mã hóa vĩnh viễn. Sau khi thoát khỏi bảng điều khiển python và bắt đầu lại, mã hóa vẫn như cũ
macemers

37
Cảm ơn! Nhưng tại sao chúng ta cần tải lại sys sau khi nhập nó?
Dmiters

6
@DmitryNarkevich, vì chức năng setdefaultencoding ảo tưởng . Nó đã bị xóa khi khởi động Python vì nó không bao giờ nên là một phần của bản phát hành thích hợp ở nơi đầu tiên, rõ ràng.
prei

3
Điều đó có nghĩa là bạn chưa khắc phục được nguyên nhân gốc rễ. Bạn vừa vá bất kỳ chuyển đổi ngụ ý nào
Alastair McCormack

5
@miraculixx Mã hóa mặc định của Python 3 là UTF-8 với các chuỗi Unicode làm mặc định str, vì vậy nó không quá hạn ở đó. Trong Python 2.x, Unicode ở trạng thái chuyển đổi, do đó sẽ rất nguy hiểm khi giả định mã hóa khi chuyển đổi byte thành Unicodes. Do đó, mã hóa mặc định ASCII của Py2 là sự lựa chọn có chủ ý và tại sao việc thay đổi mã hóa mặc định đòi hỏi phải có sự cố tình tải lại sys. Cách chính xác để loại bỏ lỗi mã hóa trong Py2 là giải mã rõ ràng và mã hóa chuỗi (byte) thành Unicode, khi cần chuyển đổi - không chỉ giả sử các chuỗi được mã hóa UTF-8.
Alastair McCormack

130

Đây là "vấn đề unicode" cổ điển. Tôi tin rằng việc giải thích điều này nằm ngoài phạm vi của câu trả lời StackOverflow để giải thích hoàn toàn những gì đang xảy ra.

Nó cũng được giải thích ở đây .

Tóm lại, bạn đã chuyển một cái gì đó đang được hiểu là một chuỗi byte sang thứ gì đó cần giải mã nó thành các ký tự Unicode, nhưng codec mặc định (ascii) không thành công.

Bài thuyết trình tôi chỉ cho bạn để cung cấp lời khuyên để tránh điều này. Làm cho mã của bạn thành một "bánh sandwich unicode". Trong Python 2, việc sử dụng from __future__ import unicode_literalstrợ giúp.

Cập nhật: làm thế nào để sửa mã

OK - trong "nguồn" biến của bạn, bạn có một số byte. Không rõ ràng từ câu hỏi của bạn làm thế nào họ có trong đó - có thể bạn đọc chúng từ một hình thức web? Trong mọi trường hợp, chúng không được mã hóa bằng ascii, nhưng python đang cố gắng chuyển đổi chúng thành unicode giả định rằng chúng là. Bạn cần nói rõ cho nó biết mã hóa là gì. Điều này có nghĩa là bạn cần biết mã hóa là gì! Điều đó không phải lúc nào cũng dễ dàng và nó phụ thuộc hoàn toàn vào việc chuỗi này đến từ đâu. Bạn có thể thử nghiệm với một số mã hóa phổ biến - ví dụ UTF-8. Bạn nói unicode () mã hóa dưới dạng tham số thứ hai:

source = unicode(source, 'utf-8')

1
nó vẫn còn đau đầu.mr GreenAsJade, bạn có thể cho tôi một giải pháp cụ thể không?
ngư dân

1
Bạn đang hỏi "làm thế nào tôi có thể là người dùng blog này tránh được vấn đề này?". Hoặc là câu hỏi của bạn "làm thế nào tôi có thể sửa mã để vấn đề này không xảy ra"?
GreenAsJade

2
mr greenasjade: tôi nên đặt "source = unicode (nguồn, 'utf-8')" ở đâu?
ngư dân

7
Thật kỳ lạ ... sau khi phản hồi tích cực trong hơn một năm, đột nhiên hai phiếu bầu tiêu cực ... Hả?
GreenAsJade

11
sử dụng currentFile = open(filename, 'rt', encoding='latin1')hoặc currentFile = open(filename, 'rt', encoding='utf-8')- xem tại đây: stackoverflow.com/a/23917799/2047442
irudyak

42

Trong một số trường hợp, khi bạn kiểm tra mã hóa mặc định ( print sys.getdefaultencoding()), nó sẽ trả về rằng bạn đang sử dụng ASCII. Nếu bạn thay đổi thành UTF-8, nó không hoạt động, tùy thuộc vào nội dung của biến của bạn. Tôi tìm thấy một cách khác:

import sys
reload(sys)  
sys.setdefaultencoding('Cp1252')

ty, điều này đã giải quyết vấn đề của tôi với việc python ném UnicodeDecodeError vào var = u "" "chuỗi lớn khác nhau" ""
user2426679

AttributionError: mô-đun 'sys' không có thuộc tính 'setdefaultencoding'
Chaine

reload(sys)được sử dụng cho lý do cụ thể đó.
Marcin Orleansowski

1
Đã làm cho tôi ! CẢM ƠN !
Maciej

22

Tôi đã tìm kiếm để giải quyết thông báo lỗi sau:

unicodingecodeerror: 'ascii' codec không thể giải mã byte 0xe2 ở vị trí 5454: thứ tự không nằm trong phạm vi (128)

Cuối cùng tôi đã sửa nó bằng cách chỉ định 'mã hóa':

f = open('../glove/glove.6B.100d.txt', encoding="utf-8")

Mong nó cũng có thể giúp bạn.


điều này đã khắc phục lỗi cho tôi khi đọc / ghi tệp .csv, không cần bất kỳ nội dung nào khác được liệt kê trong các câu trả lời khác
user5359531

Tôi không hiểu tại sao các câu trả lời khác cung cấp nhiều chi tiết như vậy ... nhưng lại quên đi giải pháp đơn giản này. +10!
stan0

18
"UnicodeDecodeError: 'ascii' codec can't decode byte"

Nguyên nhân của lỗi này: input_ chuỗi phải là unicode nhưng str đã được đưa ra

"TypeError: Decoding Unicode is not supported"

Nguyên nhân của lỗi này: cố gắng chuyển đổi unicode input_ chuỗi thành unicode


Vì vậy, trước tiên hãy kiểm tra xem input_ chuỗi của bạn có strvà chuyển đổi sang unicode nếu cần:

if isinstance(input_string, str):
   input_string = unicode(input_string, 'utf-8')

Thứ hai, ở trên chỉ thay đổi loại nhưng không loại bỏ các ký tự không phải mã ascii. Nếu bạn muốn xóa các ký tự không phải mã ascii:

if isinstance(input_string, str):
   input_string = input_string.decode('ascii', 'ignore').encode('ascii') #note: this removes the character and encodes back to string.

elif isinstance(input_string, unicode):
   input_string = input_string.encode('ascii', 'ignore')

9

Tôi thấy điều tốt nhất là luôn luôn chuyển đổi sang unicode - nhưng điều này rất khó đạt được vì trong thực tế, bạn phải kiểm tra và chuyển đổi mọi đối số cho mọi hàm và phương thức bạn từng viết bao gồm một số hình thức xử lý chuỗi.

Vì vậy, tôi đã đưa ra cách tiếp cận sau đây để đảm bảo chuỗi unicodes hoặc chuỗi byte, từ đầu vào. Tóm lại, bao gồm và sử dụng lambdas sau:

# guarantee unicode string
_u = lambda t: t.decode('UTF-8', 'replace') if isinstance(t, str) else t
_uu = lambda *tt: tuple(_u(t) for t in tt) 
# guarantee byte string in UTF8 encoding
_u8 = lambda t: t.encode('UTF-8', 'replace') if isinstance(t, unicode) else t
_uu8 = lambda *tt: tuple(_u8(t) for t in tt)

Ví dụ:

text='Some string with codes > 127, like Zürich'
utext=u'Some string with codes > 127, like Zürich'
print "==> with _u, _uu"
print _u(text), type(_u(text))
print _u(utext), type(_u(utext))
print _uu(text, utext), type(_uu(text, utext))
print "==> with u8, uu8"
print _u8(text), type(_u8(text))
print _u8(utext), type(_u8(utext))
print _uu8(text, utext), type(_uu8(text, utext))
# with % formatting, always use _u() and _uu()
print "Some unknown input %s" % _u(text)
print "Multiple inputs %s, %s" % _uu(text, text)
# but with string.format be sure to always work with unicode strings
print u"Also works with formats: {}".format(_u(text))
print u"Also works with formats: {},{}".format(*_uu(text, text))
# ... or use _u8 and _uu8, because string.format expects byte strings
print "Also works with formats: {}".format(_u8(text))
print "Also works with formats: {},{}".format(*_uu8(text, text))

Đây là một số lý do thêm về điều này .


Xin chào, trong Python 3, hàm _u nó không hoạt động với giá trị này 'Ita £'.
Martin

1
Ok, bắt đầu từ "lý luận" của bạn ở đâu? print unicode(u'Zürich', encoding="UTF-8")và sau đó phàn nàn "Nhưng thật đáng ngạc nhiên, bạn không thể mã hóa unicode ext thành UTF8". unicode()không mã hóa; nó giải mã và bạn không thể giải mã Unicode - nó đã được giải mã rồi!
Alastair McCormack

@AlastairMcCormack Bạn được chào đón nhất để cải thiện bài viết. Tuy nhiên, nếu bạn thích rắc rắc sự cao siêu bị cáo buộc của mình lên những người khác không chia sẻ ý kiến ​​và hiểu biết của bạn, thì tôi thực sự không quan tâm. Cảm ơn bạn.
miraculixx

3
@miraculixx Tôi xin lỗi, tôi không có ý định đi qua như một thằng ngốc. Lo lắng về việc giải mã và mã hóa mỗi khi bạn sử dụng một chuỗi trong mã của bạn là không cần thiết.
Alastair McCormack

7

Để giải quyết vấn đề này ở cấp độ hệ điều hành trong bản cài đặt Ubuntu, hãy kiểm tra như sau:

$ locale charmap

Nếu bạn nhận được

locale: Cannot set LC_CTYPE to default locale: No such file or directory

thay vì

UTF-8

sau đó thiết lập LC_CTYPELC_ALLnhư thế này:

$ export LC_ALL="en_US.UTF-8"
$ export LC_CTYPE="en_US.UTF-8"

6

Mã hóa chuyển đổi một đối tượng unicode thành một đối tượng chuỗi. Tôi nghĩ rằng bạn đang cố mã hóa một đối tượng chuỗi. đầu tiên chuyển đổi kết quả của bạn thành đối tượng unicode và sau đó mã hóa đối tượng unicode đó thành 'utf-8'. ví dụ

    result = yourFunction()
    result.decode().encode('utf-8')

4

Tôi đã có cùng một vấn đề nhưng nó không hoạt động với Python 3. Tôi đã làm theo và nó đã giải quyết vấn đề của tôi:

enc = sys.getdefaultencoding()
file = open(menu, "r", encoding = enc)

Bạn phải đặt mã hóa khi bạn đang đọc / ghi tệp.


4

Có một lỗi tương tự và điều này đã giải quyết lỗi của tôi. Cảm ơn! python 2 và python 3 khác nhau trong việc xử lý unicode đang làm cho các tệp ngâm không tương thích với tải. Vì vậy, sử dụng đối số mã hóa của python Pickle. Liên kết dưới đây đã giúp tôi giải quyết vấn đề tương tự khi tôi đang cố mở dữ liệu đã được lấy từ python 3.7, trong khi tệp của tôi được lưu ban đầu trong phiên bản python 2.x. https://blog.modest-destiny.com/posts/python-2-and-3-compiverse-pickle-save-and-load/ Tôi sao chép hàm load_pickle trong tập lệnh của mình và gọi hàm load_pickle (pickle_file) trong khi tải input_data như thế này:

input_data = load_pickle("my_dataset.pkl")

Hàm load_pickle có ở đây:

def load_pickle(pickle_file):
    try:
        with open(pickle_file, 'rb') as f:
            pickle_data = pickle.load(f)
    except UnicodeDecodeError as e:
        with open(pickle_file, 'rb') as f:
            pickle_data = pickle.load(f, encoding='latin1')
    except Exception as e:
        print('Unable to load data ', pickle_file, ':', e)
        raise
    return pickle_data

1
tốt hơn là bao gồm định nghĩa của load_picklechức năng trong câu trả lời của bạn.
Tweetsash

4

Điều này làm việc cho tôi:

    file = open('docs/my_messy_doc.pdf', 'rb')

3

Nói tóm lại, để đảm bảo xử lý unicode thích hợp trong Python 2:

  • sử dụng io.openđể đọc / ghi tập tin
  • sử dụng from __future__ import unicode_literals
  • cấu hình các đầu vào / đầu ra dữ liệu khác (ví dụ: cơ sở dữ liệu, mạng) để sử dụng unicode
  • nếu bạn không thể định cấu hình đầu ra thành utf-8, hãy chuyển đổi đầu ra của bạn cho chúng print(text.encode('ascii', 'replace').decode())

Để biết giải thích, hãy xem câu trả lời chi tiết của @Alastair McCormack .


• sử dụng io.open(path, 'r', encoding='utf-8')để đọc các tập tin được mã hóa utf-8.
Bob Stein

3

Tôi đã có cùng một lỗi, với các URL chứa ký tự không phải mã ascii (byte có giá trị> 128), giải pháp của tôi:

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

Lưu ý: utf-8, utf8 chỉ đơn giản là bí danh. Chỉ sử dụng 'utf8' hoặc 'utf-8' sẽ hoạt động theo cùng một cách

Trong trường hợp của tôi, đã làm việc cho tôi, trong Python 2.7, tôi cho rằng phép gán này đã thay đổi 'một cái gì đó' trong strbiểu diễn bên trong - nghĩa là, nó buộc phải 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ả các phép thuật ở đúng nơi Unicode trong Python là ma thuật đen đối với tôi. Hy vọng hữu ích


1
Tại sao một dấu gạch ngang trong một mà không phải là khác
IgorGanapolsky

1
Python chấp nhận bí danh cho tên mã hóa, tôi đã thử và thực hiện tương tự ... đơn giản là tôi không nhận thấy rằng tôi đã viết chúng khác nhau, ghi chú thêm
Fabiano Tarlao

2

Tôi gặp vấn đề tương tự với chuỗi "PastelerÃa Mallorca" và tôi đã giải quyết bằng:

unicode("Pastelería Mallorca", 'latin-1')

1

Trong một dự án Django (1.9.10) / Python 2.7.5, tôi có các UnicodeDecodeErrorngoại lệ thường xuyên ; chủ yếu là khi tôi cố gắng cung cấp chuỗi unicode để đăng nhập. Tôi đã tạo một hàm trợ giúp cho các đối tượng tùy ý định dạng cơ bản thành chuỗi ascii 8 bit và thay thế bất kỳ ký tự nào không có trong bảng thành '?'. Tôi nghĩ đó không phải là giải pháp tốt nhất nhưng vì mã hóa mặc định là ascii (và tôi không muốn thay đổi nó) nên nó sẽ làm:

def encode_for_logging (c, mã hóa = 'ascii'):
    nếu isinstance (c, basestring):
        trả về c.encode (mã hóa, 'thay thế')
    elif isinstance (c, Iterable):
        c_ = []
        cho v trong c:
            c_.append (encode_for_logging (v, mã hóa))
        trả lại c_
    khác:
        trả về encode_for_logging (unicode (c))
`


1

Lỗi này xảy ra khi có một số ký tự không phải ASCII trong chuỗi của chúng tôi và chúng tôi đang thực hiện bất kỳ thao tác nào trên chuỗi đó mà không giải mã đúng. Điều này giúp tôi giải quyết vấn đề của mình. Tôi đang đọc tệp CSV có ID cột, Văn bản và giải mã các ký tự trong đó như sau:

train_df = pd.read_csv("Example.csv")
train_data = train_df.values
for i in train_data:
    print("ID :" + i[0])
    text = i[1].decode("utf-8",errors="ignore").strip().lower()
    print("Text: " + text)

0

Đây là giải pháp của tôi, chỉ cần thêm mã hóa. with open(file, encoding='utf8') as f

Và vì việc đọc tệp găng tay sẽ mất nhiều thời gian, tôi khuyên bạn nên sử dụng tệp găng tay cho một tệp numpy. Khi netx bạn đọc trọng lượng nhúng, nó sẽ tiết kiệm thời gian của bạn.

import numpy as np
from tqdm import tqdm


def load_glove(file):
    """Loads GloVe vectors in numpy array.
    Args:
        file (str): a path to a glove file.
    Return:
        dict: a dict of numpy arrays.
    """
    embeddings_index = {}
    with open(file, encoding='utf8') as f:
        for i, line in tqdm(enumerate(f)):
            values = line.split()
            word = ''.join(values[:-300])
            coefs = np.asarray(values[-300:], dtype='float32')
            embeddings_index[word] = coefs

    return embeddings_index

# EMBEDDING_PATH = '../embedding_weights/glove.840B.300d.txt'
EMBEDDING_PATH = 'glove.840B.300d.txt'
embeddings = load_glove(EMBEDDING_PATH)

np.save('glove_embeddings.npy', embeddings) 

Liên kết chính: https://gist.github.com/BrambleXu/634a844cdd3cd04bb2e3ba3c83aef227


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.