2011-04-05 17 views
133

क्यों नीचे दिए गए आइटम विफल हो रहा है? और यह "लैटिन -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' 

(ध्यान दें, मैं अजगर 2 का मिश्रण का उपयोग कर रहा है और यहां 3 प्रतिनिधित्व। इनपुट पायथन के किसी भी संस्करण में मान्य है, लेकिन आपके पायथन दुभाषिया वास्तव में इस तरह से यूनिकोड और बाइट स्ट्रिंग दोनों को दिखाने की संभावना नहीं है।)

+1

धन्यवाद (और दूसरे ने उत्तर दिया), मैं गलत धारणा के तहत था कि 255 तक सीधे बदल जाएगा। – RuiDC

44

यह अवैध UTF-8 है। यह चरित्र आईएसओ-लैटिन 1 में ई-तीव्र चरित्र है, यही कारण है कि यह उस कोडसेट के साथ सफल होता है।

आप codeset आप में तार प्राप्त कर रहे हैं पता नहीं है, तो आप मुसीबत का एक सा कर रहे हैं। यह सबसे अच्छा होगा यदि आपके प्रोटोकॉल/एप्लिकेशन के लिए एक कोडसेट (उम्मीद है कि यूटीएफ -8) चुना जाएगा और फिर आप उन लोगों को अस्वीकार कर देंगे जो डीकोड नहीं करते हैं।

आप ऐसा नहीं कर सकते हैं, तो आप heuristics की आवश्यकता होगी।

+19

+1:

समाधान के लिए 'लैटिन -1' एन्कोडिंग बदलने के थे। – meshy

+2

और हेरिस्टिक्स के लिए, कार्डेट लाइब्रेरी देखें। – mlissner

33

क्योंकि UTF-8 multibyte है और कोई चार \xe9 के अपने संयोजन के साथ साथ अंतरिक्ष निम्नलिखित करने के लिए इसी है।

यह दोनों utf-8 और लैटिन -1 में क्यों सफल होना चाहिए?

यहाँ कैसे एक ही वाक्य utf-8 में होना चाहिए:

+0

लैटिन -1 एक एकल बाइट एन्कोडिंग परिवार तो यह सब कुछ UTF-8 में परिभाषित किया जाना चाहिए है। लेकिन क्यों लैटिन -1 जीतता है? –

64

मुझे एक ही त्रुटि हुई जब मैंने एक सीएसवी फ़ाइल खोलने की कोशिश की pandas read_csv विधि द्वारा। कह क्या चरित्र है के लिए

pd.read_csv('ml-100k/u.item', sep='|', names=m_cols , encoding='latin-1') 
संबंधित मुद्दे