2012-07-05 14 views
43

यहां त्रुटि संदेशों के साथ मेरे प्रयास हैं। मैं क्या गलत कर रहा हूं?स्ट्रिंग एन्कोडिंग और डिकोडिंग?

string.decode("ascii", "ignore") 

UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 37: ordinal not in range(128)

string.encode('utf-8', "ignore") 

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 37: ordinal not in range(128)

+0

'string' का मूल्य क्या है? यह किस प्रकार का है? –

+0

यूनिकोड ऑब्जेक्ट को डीकोड करने का अर्थ नहीं है क्योंकि यह पहले से ही डीकोडेड रूप में है। जब आप unicode_object.decode() को कॉल करते हैं, तो Python मानता है कि आप इसके बजाय यूनिकोड में बाइट स्ट्रिंग को डीकोड करना चाहते हैं। यह पहले यूनिकोड ऑब्जेक्ट को आपके सिस्टम के डिफ़ॉल्ट एन्कोडिंग का उपयोग करके बाइट स्ट्रिंग के रूप में एन्कोड करने का प्रयास करता है - यह वास्तविक त्रुटि है जिसे आप देख रहे हैं। – kumar303

उत्तर

74

आप एक unicode डिकोड नहीं कर सकते हैं, और आप एक str सांकेतिक शब्दों में बदलना नहीं कर सकते। इसे the other way around करने का प्रयास करें।

+6

सटीक लेकिन संभवतः थोड़ा सा टेलीग्राफिक इसलिए मैंने एक और विस्तृत स्पष्टीकरण जोड़ा है। – Duncan

+1

समझदार शब्द ... मेरी इच्छा है कि मैंने पहले पढ़ा था कि – Remiz

+6

क्या मैं अकेला हूं जो सोचता है कि पाइथन के पास यह गलत तरीका है? जब मैं एक पाइथन स्ट्रिंग को अपने बाइनरी यूटीएफ -8 प्रस्तुति में बदलता हूं, निश्चित रूप से इसे "एन्कोडिंग" कहा जाना चाहिए, और दूसरी तरफ नहीं? –

2

ऐसा इसलिए है क्योंकि आपकी इनपुट स्ट्रिंग को एन्कोडिंग नियमों (डिफ़ॉल्ट रूप से सख्त) के अनुसार परिवर्तित नहीं किया जा सकता है।

मैं नहीं जानता, लेकिन मैं हमेशा सीधे यूनिकोड() निर्माता का उपयोग कर इनकोडिंग, कम से कम है कि official documentation पर तरीके है:

unicode(your_str, errors="ignore") 
+0

धन्यवाद इसने मेरी मदद की। – ashim888

+1

यह स्ट्रिंग से गैर-ASCII वर्ण हटा देता है। ('यूनिकोड (" \ xe2 \ x9d \ xa4 ", त्रुटियां = 'अनदेखा करें') 'आपको' देता है।) यदि यह एक स्वीकार्य परिणाम है, तो यह ठीक हो सकता है। मैं कल्पना नहीं कर सकता कि अधिकांश स्थितियों में डेटा खोना ठीक है। कम से कम, इस जवाब को करने की उचितता पर विस्तार करने की आवश्यकता है। – jpmc26

54

सभी मूल प्रश्न में शामिल करना ज़रूरी चीज़ों को भाँप रहे हैं, लेकिन, पाइथन 2.x मानते हुए त्रुटि संदेशों को ध्यान से पढ़ना है: विशेष रूप से जहां आप 'एन्कोड' कहते हैं लेकिन संदेश 'डीकोड' और इसके विपरीत, संदेशों में शामिल मानों के प्रकार भी कहते हैं।

पहला उदाहरण string में प्रकार unicode की है और आप इसे जिन्हें किसी ऑपरेशन एक बाइट स्ट्रिंग यूनिकोड में कनवर्ट है डिकोड करने का प्रयास किया। अजगर काम आते हुए डिफ़ॉल्ट 'ascii' एन्कोडिंग का उपयोग str को यूनिकोड मान परिवर्तित करने का प्रयास लेकिन जब से अपने स्ट्रिंग एक गैर ASCII वर्ण समाहित आप त्रुटि जो कहता है कि अजगर एनकोड एक यूनिकोड मूल्य करने में असमर्थ था मिल गया।

>>> u"\xa0".decode("ascii", "ignore") 

Traceback (most recent call last): 
    File "<pyshell#7>", line 1, in <module> 
    u"\xa0".decode("ascii", "ignore") 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 0: ordinal not in range(128) 

आप रिवर्स एक बाइट स्ट्रिंग सांकेतिक शब्दों में बदलना करने के लिए प्रयास करते हैं दूसरे मामले में: यहाँ एक उदाहरण है जो इनपुट स्ट्रिंग के प्रकार से पता चलता है।

>>> "\xc2".encode("ascii", "ignore") 

Traceback (most recent call last): 
    File "<pyshell#6>", line 1, in <module> 
    "\xc2".encode("ascii", "ignore") 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 0: ordinal not in range(128) 
+0

यह मैंने कभी भी पढ़ा है इस समस्या का सबसे अच्छा स्पष्टीकरण है। – cerberos

+0

यह मिथक बताता है। – foresightyj

21

तरफ से: एन्कोडिंग एक ऑपरेशन, एक बाइट स्ट्रिंग के लिए यूनिकोड में परिवर्तित कर देती अजगर सहायक के पहले और यूनिकोड करने के लिए अपने बाइट स्ट्रिंग परिवर्तित करने के लिए प्रयास करता है क्योंकि आप इसे एक ascii स्ट्रिंग डिफ़ॉल्ट ascii विकोडक विफल रहता है नहीं दिया है decode और encode पीछे की ओर, मुझे लगता है कि यहां उत्तर का हिस्सा वास्तव में ascii एन्कोडिंग का उपयोग न करें। शायद यह नहीं है कि आप क्या चाहते हैं।

आरंभ करने के लिए, str के बारे में सोचें जैसे कि आप एक सादा पाठ फ़ाइल करेंगे। यह केवल बाइट्स का एक समूह है जिसमें वास्तव में कोई एन्कोडिंग संलग्न नहीं है। इसका अर्थ यह है कि कोड के किसी भी हिस्से को पढ़ने के लिए यह है। यदि आपको नहीं पता कि यह अनुच्छेद किस बारे में बात कर रहा है, तो आगे जाने से पहले जोएल के The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets को अभी पढ़ें।

स्वाभाविक रूप से, हम सब उस गड़बड़ी से अवगत हैं जो बनाया गया है। जवाब, कम से कम स्मृति के भीतर, सभी तारों के लिए एक मानक एन्कोडिंग है। यही वह जगह है जहां unicode आता है। मुझे निश्चित रूप से यह सुनिश्चित करने में परेशानी हो रही है कि पाइथन आंतरिक रूप से किस एन्कोडिंग का उपयोग करता है, लेकिन यह वास्तव में इसके लिए कोई फर्क नहीं पड़ता। मुद्दा यह है कि आप जानते हैं कि यह बाइट्स का अनुक्रम है जिसे एक निश्चित तरीके से व्याख्या किया गया है। तो आपको केवल पात्रों के बारे में सोचने की जरूरत है, बाइट्स नहीं।

समस्या यह है कि अभ्यास में, आप दोनों में भाग लेते हैं।कुछ पुस्तकालय आपको str देते हैं, और कुछ str की अपेक्षा करते हैं। निश्चित रूप से यह समझ में आता है जब भी आप बाइट्स की एक श्रृंखला स्ट्रीम कर रहे हैं (जैसे कि डिस्क से या वेब अनुरोध पर)। तो आपको आगे और आगे अनुवाद करने में सक्षम होना चाहिए।

codecs दर्ज करें: यह इन दो डेटा प्रकारों के बीच अनुवाद पुस्तकालय है। आप encode का उपयोग किसी पाठ स्ट्रिंग (unicode) से बाइट (str) के एक दृश्य उत्पन्न करने के लिए, और आप decode का उपयोग बाइट्स की एक दृश्य (str) से एक पाठ स्ट्रिंग (unicode) प्राप्त करने के लिए।

>>> s = "I look like a string, but I'm actually a sequence of bytes. \xe2\x9d\xa4" 
>>> codecs.decode(s, 'utf-8') 
u"I look like a string, but I'm actually a sequence of bytes. \u2764" 

यहाँ क्या हुआ:

उदाहरण के लिए

? मैंने पायथन को बाइट्स का अनुक्रम दिया, और फिर मैंने इसे बताया, "मुझे unicode संस्करण दें, यह देखते हुए कि बाइट्स का यह अनुक्रम 'utf-8' में है।" जैसा मैंने पूछा था, और उन बाइट्स (a heart character) अब पूरी तरह से इलाज किए जाते हैं, जो उनके यूनिकोड कोडपॉइंट द्वारा दर्शाए जाते हैं।

के अन्य तरीके से चारों ओर चलते हैं:

>>> u = u"I'm a string! Really! \u2764" 
>>> codecs.encode(u, 'utf-8') 
"I'm a string! Really! \xe2\x9d\xa4" 

मैं अजगर एक यूनिकोड स्ट्रिंग दे दी है, और मैं इसे पूछा 'utf-8' एन्कोडिंग का उपयोग बाइट्स के अनुक्रम में स्ट्रिंग अनुवाद करने के लिए। तो ऐसा हुआ, और अब दिल केवल बाइट्स का एक गुच्छा है जो एएससीआईआई के रूप में प्रिंट नहीं कर सकता है; तो यह मुझे इसके बजाय हेक्साडेसिमल दिखाता है।

हम भी, निश्चित रूप से अन्य एन्कोडिंग के साथ काम कर सकते हैं:

>>> s = "I have a section \xa7" 
>>> codecs.decode(s, 'latin1') 
u'I have a section \xa7' 
>>> codecs.decode(s, 'latin1')[-1] == u'\u00A7' 
True 

>>> u = u"I have a section \u00a7" 
>>> u 
u'I have a section \xa7' 
>>> codecs.encode(u, 'latin1') 
'I have a section \xa7' 

(। '\xa7' दोनों यूनिकोड और लैटिन -1 में section character है,)

अपने प्रश्न के लिए

तो, आप पहली बार क्या में अपने str एन्कोडिंग है यह पता लगाने की जरूरत है।

  • यह एक फ़ाइल से आया था? वेब अनुरोध से? अपने डेटाबेस से? फिर स्रोत एन्कोडिंग निर्धारित करता है। स्रोत के एन्कोडिंग का पता लगाएं और इसे unicode में अनुवाद करने के लिए उपयोग करें।

    s = [get from external source] 
    u = codecs.decode(s, 'utf-8') # Replace utf-8 with the actual input encoding 
    
  • या हो सकता है आप कहीं यह पता लिखने की कोशिश कर रहे हैं। गंतव्य की क्या एन्कोडिंग की उम्मीद है? इसका उपयोग str में अनुवाद करने के लिए करें। यूटीएफ -8 सादे पाठ दस्तावेजों के लिए एक अच्छा विकल्प है; ज्यादातर चीजें इसे पढ़ सकते हैं।

    u = u'My string' 
    s = codecs.encode(u, 'utf-8') # Replace utf-8 with the actual output encoding 
    [Write s out somewhere] 
    
  • तुम सिर्फ अंतर या कुछ और के लिए स्मृति में आगे और पीछे का अनुवाद कर रहे हैं? फिर बस एक एन्कोडिंग चुनें और इसके साथ चिपके रहें;

    u = u'My string' 
    s = codecs.encode(u, 'utf-8') 
    newu = codecs.decode(s, 'utf-8') 
    

आधुनिक प्रोग्रामिंग में, आप शायद कभी नहीं इस से किसी के लिए 'ascii' एन्कोडिंग का उपयोग करना: 'utf-8' शायद उस के लिए सबसे अच्छा विकल्प है। यह सभी संभावित पात्रों का एक बहुत ही छोटा सबसेट है, और मुझे पता नहीं है कि कोई भी प्रणाली डिफ़ॉल्ट या कुछ भी इसका उपयोग करती है।

अजगर 3 बस नाम बदल कर इस बेहद स्पष्ट करने का पूरा प्रयास करता।पायथन 3 में, str को bytes के साथ प्रतिस्थापित किया गया था, और unicode को str के साथ प्रतिस्थापित किया गया था।

+0

सुंदर स्पष्टीकरण !!! –

संबंधित मुद्दे