2011-04-05 27 views
133

Aşağıdaki öğe neden başarısız oluyor? ve neden "latin-1" kodeki ile başarılı oluyor? içindeUnicodeDecodeError, geçersiz devamı bayt

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

sonuçları:

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 

cevap

145

ikili olarak, 0xE9 1110 1001 benziyor. UTF-8 on Wikipedia hakkında okursanız, böyle bir baytın 10xx xxxx formundan iki tanesini takip etmesi gerektiğini görürsünüz. Örneğin, örneğin:

Ancak bu yalnızca istisnanın mekanik nedenidir. Bu durumda, UTF-8 ve Latin 1 nasıl görüneceğini görebilirsiniz neredeyse kesin latin 1. kodlanmış bir dize sahip farklı:

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

(Python 2 bir karışımını kullanıyorum, dikkat ve Burada 3 gösterim Giriş Python'un herhangi bir sürümünde geçerlidir, ancak Python yorumlayıcınızın aslında bu şekilde hem unicode hem de bayt dizgileri göstermesi olası değildir.)

+1

Teşekkürler (ve cevaplayan diğerine), 255'e kadar olan karakterlerin doğrudan dönüşebileceği şeklindeki yanlış inanıştaydım. – RuiDC

44

geçersiz UTF-8'dir. Bu karakter, ISO-Latin1'deki e-akut karakterdir, bu yüzden bu kod kümesiyle başarılı olur.

Dizeleri aldığınız kod setini bilmiyorsanız, sorun yaşarsınız. Protokolünüz/uygulamanız için tek bir kod kümesi (umarım UTF-8) seçilip kod çözmeyenleri reddetmeniz en iyisidir.

Bunu yapamazsanız, sezgisel olmanız gerekir.

+19

+1 karakter ne olduğunu söyleyerek:

çözüm

'latin-1' olarak kodlamasını değiştirmek oldu. – meshy

+2

Ve sezgisel bilgi için, chardet kitaplığına bakın. – mlissner

33

UTF-8 çok baytlı olduğundan ve \xe9 kombinasyonunuza karşılık gelen hiçbir char yoksa artı takip eden alan yoktur.

Neden utf-8 ve latin-1? Aynı cümle utf-8 olmalıdır İşte nasıl

:

+0

Latin-1, tek bir bayt kodlama ailesidir, böylece her şey UTF-8'de tanımlanmalıdır. Ama neden Latin-1 bazen kazanıyor? –

64

Bir csv dosyasını açmaya çalıştığımda aynı hatayı aldım pandas read_csv yöntemiyle.

pd.read_csv('ml-100k/u.item', sep='|', names=m_cols , encoding='latin-1') 
İlgili konular