2011-04-05 94 views
133

爲什麼下面的項目失敗?爲什麼用「latin-1」編解碼器取得成功?UnicodeDecodeError,無效延續字節

o = "a test of \xe9 char" #I want this to remain a string as this is what I am receiving 
v = o.decode("utf-8") 

結果:

Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
File "C:\Python27\lib\encodings\utf_8.py", 
line 16, in decode 
    return codecs.utf_8_decode(input, errors, True) UnicodeDecodeError: 
'utf8' codec can't decode byte 0xe9 in position 10: invalid continuation byte 

回答

145

在二進制,0xE9看起來像1110 1001。如果你閱讀了大約UTF-8 on Wikipedia,你會發現這樣一個字節後面必須跟着兩個10xx xxxx。因此,例如:

>>> b'\xe9\x80\x80'.decode('utf-8') 
u'\u9000' 

但這只是異常的機械原因。在這種情況下,你有一個是拉美1.幾乎可以肯定編碼的字符串,你可以看到UTF-8和拉丁美洲1如何看待不同:

>>> u'\xe9'.encode('utf-8') 
b'\xc3\xa9' 
>>> u'\xe9'.encode('latin-1') 
b'\xe9' 

(請注意,我使用Python 2的組合和3代表這裏。輸入在任何版本的Python中都是有效的,但是你的Python解釋器不可能真正以這種方式顯示Unicode和字節串)。

+1

謝謝(和其他答覆),我錯誤地認爲直到255會直接轉換。 – RuiDC 2011-04-05 15:28:48

44

它是無效的UTF-8。該字符是ISO-Latin1中的e-sharp字符,這就是爲什麼它能夠成功使用該代碼集。

如果您不知道接收字符串的代碼集,那麼您遇到了一些麻煩。如果爲你的協議/應用程序選擇一個單一的代碼集(最好是UTF-8),那麼你最好是拒絕那些沒有解碼的代碼。

如果你不能這樣做,你需要啓發式。

+19

+1這麼說的性格是什麼。 – meshy 2012-09-15 15:41:09

+2

有關啓發式,請參閱chardet庫。 – mlissner 2012-10-23 15:48:46

33

由於UTF-8是多字節且沒有與您的組合\xe9以及以下空格對應的字符。

爲什麼它應該成功都是 utf-8和latin-1?

相同的句子應該怎麼在這裏是UTF-8:

+0

Latin-1是一個單字節編碼族,因此它的所有內容都應該用UTF-8定義。但爲什麼有時拉丁文-1勝出? – 2018-03-02 00:18:34

64

當我試圖打開一個csv文件時由pandas read_csv方法。

的解決辦法是改變編碼爲 '拉丁-1':

pd.read_csv('ml-100k/u.item', sep='|', names=m_cols , encoding='latin-1') 
相關問題