एनकोड / डिकोड के बीच अंतर क्या है?


180

मुझे कभी यकीन नहीं हुआ कि मैं str / यूनिकोड डिकोड और एनकोड के बीच का अंतर समझता हूँ।

मुझे पता है कि str().decode()जब आपके पास बाइट्स का एक स्ट्रिंग होता है, तो आपको पता होता है कि एक निश्चित वर्ण एन्कोडिंग है, जिसे एन्कोडिंग नाम दिया गया है, यह एक यूनिकोड स्ट्रिंग लौटाएगा।

मुझे पता है कि unicode().encode()एक दिए गए एन्कोडिंग नाम के अनुसार यूनिकोड चार्ट को बाइट्स के स्ट्रिंग में परिवर्तित करता है।

लेकिन मुझे समझ नहीं आ रहा है कि क्या हैं str().encode()और क्या unicode().decode()हैं। किसी को भी समझा सकते हैं, और संभवतः कुछ और भी सही है जो मैंने ऊपर गलत किया है?

संपादित करें:

कई उत्तर .encodeएक स्ट्रिंग पर क्या करते हैं, इस बारे में जानकारी देते हैं , लेकिन किसी को भी पता नहीं लगता है कि .decodeयूनिकोड क्या करता है।


मुझे लगता है कि इस पृष्ठ का दूसरा उत्तर पर्याप्त और संक्षिप्त है।
बेन

जवाबों:


106

decodeयूनिकोड स्ट्रिंग्स की विधि में वास्तव में कोई एप्लिकेशन नहीं है (जब तक कि आपके पास किसी कारण से यूनिकोड स्ट्रिंग में कुछ गैर-पाठ डेटा नहीं है - नीचे देखें)। यह मुख्य रूप से ऐतिहासिक कारणों से है, मुझे लगता है। पायथन 3 में यह पूरी तरह से चला गया है।

unicode().decode()डिफ़ॉल्ट (ascii) कोडेक का उपयोग कर के एक अंतर्निहित एन्कोडिंग प्रदर्शन करेगा s। इसे इस तरह सत्यापित करें:

>>> s = u'ö'
>>> s.decode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 0:
ordinal not in range(128)

>>> s.encode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 0:
ordinal not in range(128)

त्रुटि संदेश बिल्कुल समान हैं।

इसके लिए str().encode()यह दूसरा तरीका है - यह डिफ़ॉल्ट एन्कोडिंग के साथ एक अंतर्निहित डिकोडिंग का प्रयास करता है s:

>>> s = 'ö'
>>> s.decode('utf-8')
u'\xf6'
>>> s.encode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0:
ordinal not in range(128)

इस तरह से उपयोग किया जाता है, str().encode()यह भी शानदार है।

लेकिन बाद के तरीके का एक और अनुप्रयोग है जो उपयोगी है: ऐसे एन्कोडिंग हैं जिनका चरित्र सेट से कोई लेना-देना नहीं है, और इस प्रकार 8-बिट स्ट्रिंग्स को एक सार्थक तरीके से लागू किया जा सकता है:

>>> s.encode('zip')
'x\x9c;\xbc\r\x00\x02>\x01z'

आप सही हैं, हालांकि: इन दोनों अनुप्रयोगों के लिए "एन्कोडिंग" का अस्पष्ट उपयोग ... अजीब है। फिर से, पायथन 3 में अलग byteऔर stringप्रकार के साथ , यह अब एक मुद्दा नहीं है।


4
.decode()यूनिकोड के तार उपयोगी हो सकते हैं जैसे,print u'\\u0203'.decode('unicode-escape')
jfs

अच्छा उदाहरण @JFSebastian python3 में मुझे लगता है कि आप क्या करेंगे:print u'\\u0203'.encode('utf8').decode('unicode-escape')
AJP

1
@AJP: पायथन 3 पर:codecs.decode(u'\\u0203', 'unicode-escape')
jfs

@ ह: हाँ। अमान्य इनपुट और पायथन 2/3 संगतता का पता लगाने के लिए, asciiएन्कोडिंग का उपयोग करके स्ट्रिंग को स्पष्ट रूप से एन्कोड किया जा सकता है :\\u0203\u00e4'.encode('ascii').decode('unicode-escape')
jfs

@ एचओपी: आपकी पहली टिप्पणी (आपने इसे क्यों हटा दिया है? जिन टिप्पणियों का जवाब नहीं दिया गया है उन्हें हटाएं) पहले से ही कहा था। मेरा उत्तर ( .encode('ascii').decode('unicode-escape')) निर्भर नहीं करता है sys.getdefaultencoding()
jfs

71

यूनिकोड स्ट्रिंग का प्रतिनिधित्व करने के लिए बाइट्स के एक स्ट्रिंग को एन्कोडिंग के रूप में जाना जाता है । का उपयोग करें u'...'.encode(encoding)

उदाहरण:

    >>> u'utøå'.encode ('utf8')
    '\ Xc3 \ x83 \ xC2 \ xa6 \ xc3 \ x83 \ xC2 \ xb8 \ xc3 \ x83 \ xC2 \ xa5'
    >>> u'latinøå'.encode ('latin1')
    '\ Xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5'
    >>> u'asøå'.encode ('ascii')
    यूनिकोडेनाकोड: 'ascii' कोडेक 0-5 की स्थिति में वर्णों को एनकोड नहीं कर सकता है: 
    क्रम में नहीं (128)

जब भी आपको IO के लिए इसका उपयोग करने की आवश्यकता होती है, तो आप आमतौर पर एक यूनिकोड स्ट्रिंग को एन्कोड करते हैं, उदाहरण के लिए इसे नेटवर्क पर स्थानांतरित करना, या इसे डिस्क फ़ाइल में सहेजना।

यूनिकोड स्ट्रिंग के बाइट्स को परिवर्तित करने के लिए डिकोडिंग के रूप में जाना जाता है । उपयोग unicode('...', encoding)या '...'। डीकोड (एन्कोडिंग)।

उदाहरण:

   >>> u'æøå '
   यू '\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5' # दुभाषिया यूनिकोड ऑब्जेक्ट को प्रिंट करता है जैसे
   >>> यूनिकोड ('\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5', 'latin1')
   यू '\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5'
   >>> '\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5'.decode (' latin1 ')
   यू '\ xc3 \ xa6 \ xc3 \ xb8 \ xc3 \ xa5'

जब भी आप नेटवर्क से या डिस्क फ़ाइल से स्ट्रिंग डेटा प्राप्त करते हैं तब आप आमतौर पर बाइट्स की एक स्ट्रिंग को डीकोड करते हैं।

मेरा मानना ​​है कि अजगर 3 में यूनिकोड हैंडलिंग में कुछ बदलाव हैं, इसलिए ऊपर वाला अजगर 3 के लिए शायद सही नहीं है।

कुछ अच्छे लिंक:


6
आपने ओपी के सवाल का जवाब नहीं दिया। ओपी जानना चाहता है कि str.encode () और unicode.decode () क्या करते हैं। आपने अभी वही दोहराया है जो मूल प्रश्न में कहा गया था।
1

अभ्यास और डिकोडिंग में गड़बड़ी क्यों होगी, इसके लिए महान जवाब। हर मशीन वर्णों के समान सेट को नहीं समझती, लेकिन वे सभी बाइट्स को समझते हैं। सार्वभौमिक रूप से समझने वाली भाषा (जिसे डिस्क में स्थानांतरित किया जा सकता है या सहेजा जा सकता है) के लिए बाइट्स में एनकोड करें, लेकिन जब मानव को वास्तव में उन बाइट्स को पढ़ना होता है (जैसे क्लाइंट की तरफ)।
एलेक्स पेट्रालिया

शानदार जवाब! यह ऊपर जाना चाहिए !!
सैंडपाइप

16

anUnicode। एनकोड ('एन्कोडिंग') एक स्ट्रिंग ऑब्जेक्ट में परिणाम करता है और इसे यूनिकोड ऑब्जेक्ट पर कहा जा सकता है

एक स्ट्रिंग। डिकोड ('एन्कोडिंग') एक यूनिकोड ऑब्जेक्ट में परिणाम करता है और इसे एक स्ट्रिंग पर कहा जा सकता है, जो एन्कोडिंग में एन्कोडेड है।


कुछ और स्पष्टीकरण:

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

लेकिन एक समय आता है, जब आप अपने यूनिकोड ऑब्जेक्ट को कंसोल या किसी टेक्स्ट फ़ाइल में प्रिंट करना चाहते हैं। तो आपको इसे एनकोड करना होगा (उदाहरण के लिए - UTF-8 में), आप एनकोड ('utf-8') कहते हैं और आपको '\ u <someNumber>' के साथ एक स्ट्रिंग मिलती है, जो पूरी तरह से प्रिंट करने योग्य है।

फिर, फिर से - आप इसके विपरीत करना चाहेंगे - पढ़े गए स्ट्रिंग को UTF-8 में एन्कोड किया गया है और इसे एक यूनिकोड के रूप में माना जाता है, इसलिए \ u360 एक वर्ण होगा, न कि 5. फिर आप एक स्ट्रिंग (चयनित एन्कोडिंग के साथ) को डिकोड करते हैं और यूनिकोड प्रकार की बिल्कुल नई वस्तु प्राप्त करें।

एक साइड नोट के रूप में - आप कुछ विकृत एन्कोडिंग का चयन कर सकते हैं, जैसे 'ज़िप', 'बेस 64', 'रोट' और उनमें से कुछ स्ट्रिंग से स्ट्रिंग में बदल जाएंगे, लेकिन मेरा मानना ​​है कि सबसे आम मामला एक है जिसमें UTF-8 शामिल है / यूटीएफ -16 और स्ट्रिंग।


12

mybytestring.encode (somecodec) इन मूल्यों के लिए सार्थक है somecodec:

  • बेस 64
  • BZ2
  • zlib
  • हेक्स
  • quopri
  • ROT13
  • string_escape
  • तुम तुम

मुझे यकीन नहीं है कि पहले से ही डिकोड किए गए यूनिकोड पाठ को डिकोड करना किसके लिए अच्छा है। ऐसा लगता है कि किसी भी एन्कोडिंग के साथ हमेशा सिस्टम के डिफ़ॉल्ट एन्कोडिंग के साथ एनकोड करने की कोशिश करता है।


5

कुछ एनकोडिंग हैं जिनका उपयोग डे- / एन्कोड से स्ट्रेट से स्ट्रिक या यूनिकोड से यूनिकोड में किया जा सकता है। उदाहरण के लिए बेस 64, हेक्स या रोट 13 भी। वे कोडेक्स मॉड्यूल में सूचीबद्ध हैं ।

संपादित करें:

यूनिकोड स्ट्रिंग पर डिकोड संदेश संबंधित एनकोड ऑपरेशन को पूर्ववत कर सकता है:

In [1]: u'0a'.decode('hex')
Out[1]: '\n'

लौटाया गया प्रकार यूनिकोड के बजाय स्ट्रैप है जो मेरी राय में दुर्भाग्यपूर्ण है। लेकिन जब आप str और यूनिकोड के बीच एक उचित en- / decode नहीं कर रहे हैं तो यह वैसे भी गड़बड़ जैसा दिखता है।


1
-1: डिकोड विधि यूनिकोड ऑब्जेक्ट पर लागू नहीं की जा रही है। इसके बजाय, डिकोड ऑपरेशन शुरू होने से पहले यूनिकोड ऑब्जेक्ट को एक 'एससीआई' बाइटस्ट्रिंग के रूप में एनकोड किया जा रहा है। उस दावे के प्रमाण के लिए, u'ã'.decode ('हेक्स') को आज़माएं
nosklo

2
@ नोस्कोलो: आप सही कह रहे हैं। मेरा वास्तव में मतलब यह है कि यूनिकोड ऑब्जेक्ट में एक डिकोड () विधि होती है ताकि आप गैर-वर्ण-एन्कोडिंग-कोडेक्स उन पर भी लागू कर सकें। यह पूरा गैर-चरित्र-एन्कोडिंग-व्यवसाय इस इंटरफ़ेस को पायथन में गड़बड़ बनाता है <3.

1

सरल उत्तर यह है कि वे एक-दूसरे के बिल्कुल विपरीत हैं।

कंप्यूटर जानकारी को संग्रहीत करने और संसाधित करने के लिए बाइट की बहुत मूल इकाई का उपयोग करता है; यह मानवीय आंखों के लिए निरर्थक है।

उदाहरण के लिए, '\ xe4 \ xb8 \ xad \ xe6 \ x96 \ x87' दो चीनी वर्णों का प्रतिनिधित्व है, लेकिन कंप्यूटर केवल जानता है (मतलब प्रिंट या स्टोर) यह चीनी वर्ण है जब उन्हें देखने के लिए एक शब्दकोश दिया जाता है। चीनी शब्द, इस मामले में, यह एक "utf-8" शब्दकोश है, और यदि आप एक अलग या गलत शब्दकोश (एक अलग डिकोडिंग विधि का उपयोग करके) में देखें तो यह सही ढंग से इच्छित चीनी शब्द दिखाने में विफल होगा।

उपरोक्त मामले में, कंप्यूटर के लिए चीनी शब्द देखने की प्रक्रिया है decode()

और कंप्यूटर को चीनी को कंप्यूटर मेमोरी में लिखने की प्रक्रिया है encode()

तो एन्कोडेड जानकारी कच्ची बाइट्स है, और डिकोड की गई जानकारी कच्ची बाइट्स और डिक्शनरी का नाम है (लेकिन खुद डिक्शनरी नहीं)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.