स्ट्रिंग और बाइट स्ट्रिंग में क्या अंतर है?


209

मैं एक पुस्तकालय के साथ काम कर रहा हूं जो एक बाइट स्ट्रिंग देता है और मुझे इसे एक स्ट्रिंग में बदलने की आवश्यकता है।

हालांकि मुझे यकीन नहीं है कि अंतर क्या है - यदि कोई हो।

जवाबों:


260

पायथन 3 को मान लेना (पायथन 2 में, यह अंतर थोड़ा कम अच्छी तरह से परिभाषित है) - एक स्ट्रिंग वर्णों का एक अनुक्रम है, अर्थात यूनिकोड कोडप्वाइंट ; ये एक अमूर्त अवधारणा हैं, और इसे सीधे डिस्क पर संग्रहीत नहीं किया जा सकता है। एक बाइट स्ट्रिंग एक क्रम है, अनिश्चित रूप से, बाइट्स - चीजें जो डिस्क पर संग्रहीत की जा सकती हैं। उनके बीच की मैपिंग एक एन्कोडिंग है - इनमें से बहुत सारे हैं (और अनन्त रूप से कई संभव हैं) - और आपको यह जानना होगा कि रूपांतरण करने के लिए विशेष मामले में कौन सा लागू होता है, क्योंकि एक अलग एन्कोडिंग एक ही बाइट्स को मैप कर सकता है एक अलग स्ट्रिंग के लिए:

>>> b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'.decode('utf-16')
'蓏콯캁澽苏'
>>> b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'.decode('utf-8')
'τoρνoς'

एक बार जब आप जानते हैं कि किसका उपयोग करना है, तो आप .decode()बाइट स्ट्रिंग की विधि का उपयोग करके इसे ऊपर से सही वर्ण स्ट्रिंग प्राप्त कर सकते हैं। पूर्णता के लिए, .encode()वर्ण स्ट्रिंग की विधि विपरीत तरीके से जाती है:

>>> 'τoρνoς'.encode('utf-8')
b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'

7
पायथन 2 उपयोगकर्ताओं के लिए स्पष्ट करने के लिए: strप्रकार समान है bytes; यह उत्तर समान रूप से unicodeप्रकार की तुलना करता है (पायथन 3 में मौजूद नहीं है) str
क्रेयमिकेल

3
@KshitijSaraogi जो बिलकुल सच नहीं है; उस पूरे वाक्य को संपादित किया गया था और यह थोड़ा दुर्भाग्यपूर्ण है। अजगर 3 strवस्तुओं का इन-मेमोरी प्रतिनिधित्व पायथन पक्ष से सुलभ या प्रासंगिक नहीं है; डेटा संरचना कोडपॉइंट्स का सिर्फ एक अनुक्रम है। पीईपी 393 के तहत , सटीक आंतरिक एन्कोडिंग लैटिन -1, यूसीएस 2 या यूसीएस 4 में से एक है, और एक यूटीएफ -8 प्रतिनिधित्व को पहले अनुरोध के बाद कैश किया जा सकता है, लेकिन यहां तक ​​कि सी कोड को इन आंतरिक विवरणों पर भरोसा करने से हतोत्साहित किया जाता है।
LVC

1
यदि उन्हें सीधे डिस्क पर संग्रहीत नहीं किया जा सकता है, तो उन्हें मेमोरी में कैसे संग्रहीत किया जाता है?
14:33 पर z33k

2
@ बहुत बार उन्हें किसी कारणवश आंतरिक रूप से उस कारण से एनकोड करना पड़ता है , लेकिन यह आपके लिए पायथन कोड से बहुत अधिक नहीं है, जैसे कि आपको इस बात की परवाह नहीं है कि फ़्लोटिंग पॉइंट नंबर कैसे संग्रहीत किए जाते हैं।
LVC

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

390

केवल एक चीज जिसे कंप्यूटर स्टोर कर सकता है वह है बाइट्स।

कंप्यूटर में किसी भी चीज़ को स्टोर करने के लिए, आपको पहले उसे एनकोड करना होगा , यानी उसे बाइट्स में बदलना होगा। उदाहरण के लिए:

  • आप संगीत संग्रहीत करना चाहते हैं, तो आपको पहले चाहिए सांकेतिक शब्दों में बदलना इसे का उपयोग MP3, WAVआदि
  • आप एक तस्वीर संग्रहीत करना चाहते हैं, तो आपको पहले चाहिए सांकेतिक शब्दों में बदलना इसे का उपयोग PNG, JPEGआदि
  • आप पाठ संग्रहीत करना चाहते हैं, तो आपको पहले चाहिए सांकेतिक शब्दों में बदलना इसे का उपयोग ASCII, UTF-8आदि

MP3, WAV, PNG, JPEG, ASCIIऔर UTF-8के उदाहरण हैं एन्कोडिंग । एन्कोडिंग बाइट्स में ऑडियो, इमेज, टेक्स्ट आदि को दर्शाने का एक प्रारूप है।

पायथन में, एक बाइट स्ट्रिंग बस है: बाइट्स का एक क्रम। यह मानव-पठनीय नहीं है। हुड के तहत, कंप्यूटर में संग्रहीत होने से पहले सब कुछ बाइट स्ट्रिंग में परिवर्तित होना चाहिए।

दूसरी ओर, एक चरित्र स्ट्रिंग, जिसे अक्सर सिर्फ "स्ट्रिंग" कहा जाता है, पात्रों का एक क्रम है। यह मानव-पठनीय है। एक चरित्र स्ट्रिंग को सीधे कंप्यूटर में संग्रहीत नहीं किया जा सकता है, इसे पहले एनकोड करना होगा (बाइट स्ट्रिंग में परिवर्तित)। ऐसे कई एनकोडिंग हैं जिनके माध्यम से एक चरित्र स्ट्रिंग को बाइट स्ट्रिंग में परिवर्तित किया जा सकता है, जैसे ASCIIऔर UTF-8

'I am a string'.encode('ASCII')

उपरोक्त पायथन कोड 'I am a string'एन्कोडिंग का उपयोग करके स्ट्रिंग को एन्कोड करेगा ASCII। उपरोक्त कोड का परिणाम एक बाइट स्ट्रिंग होगा। यदि आप इसे प्रिंट करते हैं, तो पायथन इसका प्रतिनिधित्व करेगा b'I am a string'। हालांकि, याद रखें कि बाइट स्ट्रिंग्स मानव-पठनीय नहीं हैं , यह सिर्फ इतना है कि ASCIIजब आप उन्हें प्रिंट करते हैं तो पायथन उन्हें डिकोड करता है। पायथन में, एक बाइट स्ट्रिंग का प्रतिनिधित्व किया जाता है b, इसके बाद बाइट स्ट्रिंग का ASCIIप्रतिनिधित्व होता है।

एक बाइट स्ट्रिंग को एक वर्ण स्ट्रिंग में वापस डिकोड किया जा सकता है , अगर आपको पता है कि एन्कोडिंग जो इसे एन्कोड करने के लिए उपयोग किया गया था।

b'I am a string'.decode('ASCII')

उपरोक्त कोड मूल स्ट्रिंग लौटाएगा 'I am a string'

एन्कोडिंग और डिकोडिंग उलटा संचालन हैं। डिस्क पर लिखे जाने से पहले सब कुछ एन्कोड किया जाना चाहिए, और इसे मानव द्वारा पढ़ा जा सकने से पहले इसे डिकोड किया जाना चाहिए।


59
ज़िनाडिक्स यहाँ कुछ कुडो के योग्य है। इस वातावरण में कुछ वर्षों तक कार्य करने के बाद, वह पहली व्याख्या है जो मेरे साथ क्लिक की गई है। मैं इसे अपनी दूसरी बांह पर टैटू कर सकता हूं (एक हाथ में पहले से ही "द एब्सोल्यूट मिनिमम हर सॉफ्टवेयर डेवलपर है। बिल्कुल, यूनिकोड और कैरेक्टर सेट्स के बारे में सकारात्मक रूप से पता होना चाहिए (नो एक्सक्यूज़!) जोएल
स्पोल्स्की

4
बिल्कुल प्रतिभाशाली। स्पष्ट और समझने में आसान। हालांकि, मैं यह उल्लेख करना चाहूंगा कि यह पंक्ति - "यदि आप इसे प्रिंट करते हैं, तो पायथन इसे b'I am a string 'के रूप में प्रदर्शित करेगा" Python3 के लिए सत्य है क्योंकि Python2 बाइट्स के लिए और str एक ही बात है।
एसआरसी

5
मैं आपको इस विषय में कुछ स्पष्टता रखने के लिए एक बहुत ही मानव-पठनीय स्पष्टीकरण देने के लिए यह पुरस्कार प्रदान कर रहा हूँ!
फेडोरक्वी 'एसओ

3
बहुत बढ़िया जवाब। केवल एक चीज जो शायद जोड़ी जा सकती थी, वह अधिक स्पष्ट रूप से इंगित करने के लिए है कि ऐतिहासिक रूप से, प्रोग्रामर और प्रोग्रामिंग भाषाएं स्पष्ट रूप से या अंतर्निहित रूप से मानती हैं कि बाइट अनुक्रम और एएससीआईआई स्ट्रिंग एक ही बात थी । पायथन 3 ने स्पष्ट रूप से इस धारणा को तोड़ने का फैसला किया, सही ढंग से आईएमएचओ।
नेकोमैटिक

4
ऊपर दिए गए @ neil.millikin द्वारा उल्लिखित जोएल की पोस्ट का लिंक: joelonsoftware.com/2003/10/08/…
क्षितिज सरावगी

14

नोट: मैं पायथन 3 के लिए अपने उत्तर को अधिक विस्तृत करूंगा क्योंकि पायथन 2 के जीवन का अंत बहुत करीब है।

पायथन 3 में

bytes8-बिट अहस्ताक्षरित मानों strके अनुक्रम होते हैं , जबकि यूनिकोड कोड बिंदुओं के अनुक्रम होते हैं जो मानव भाषाओं से पाठ वर्णों का प्रतिनिधित्व करते हैं।

>>> # bytes
>>> b = b'h\x65llo'
>>> type(b)
<class 'bytes'>
>>> list(b)
[104, 101, 108, 108, 111]
>>> print(b)
b'hello'
>>>
>>> # str
>>> s = 'nai\u0308ve'
>>> type(s)
<class 'str'>
>>> list(s)
['n', 'a', 'i', '̈', 'v', 'e']
>>> print(s)
naïve

भले ही bytesऔर strएक ही तरह से काम करने के लिए लगता है, उनके उदाहरण एक दूसरे के साथ संगत नहीं हैं, यानी, bytesऔर strउदाहरणों को ऑपरेटरों के साथ मिलकर उपयोग नहीं किया जा सकता है >और +। इसके अलावा, ध्यान रखें कि समानता के लिए तुलना bytesऔर strउदाहरण, का उपयोग करते हुए ==, हमेशा मूल्यांकन करेंगे Falseयहां तक ​​कि जब वे बिल्कुल समान वर्ण होते हैं।

>>> # concatenation
>>> b'hi' + b'bye' # this is possible
b'hibye'
>>> 'hi' + 'bye' # this is also possible
'hibye'
>>> b'hi' + 'bye' # this will fail
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't concat str to bytes
>>> 'hi' + b'bye' # this will also fail
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "bytes") to str
>>>
>>> # comparison
>>> b'red' > b'blue' # this is possible
True
>>> 'red'> 'blue' # this is also possible
True
>>> b'red' > 'blue' # you can't compare bytes with str
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'bytes' and 'str'
>>> 'red' > b'blue' # you can't compare str with bytes
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'str' and 'bytes'
>>> b'blue' == 'red' # equality between str and bytes always evaluates to False
False
>>> b'blue' == 'blue' # equality between str and bytes always evaluates to False
False

किसी अन्य समस्या से निपटने के दौरान bytesऔर strमौजूद फाइलों के साथ काम करते समय मौजूद है जो openबिल्ट-इन फ़ंक्शन का उपयोग करके लौटाए जाते हैं । एक तरफ, यदि आप किसी फ़ाइल से / के लिए बाइनरी डेटा को ओटी पढ़ना या लिखना चाहते हैं, तो हमेशा बाइनरी मोड जैसे 'आरबी' या 'डब्ल्यूबी' का उपयोग करके फ़ाइल खोलें। दूसरी ओर, यदि आप किसी फ़ाइल से / तक यूनिकोड डेटा पढ़ना या लिखना चाहते हैं, तो अपने कंप्यूटर की डिफ़ॉल्ट एन्कोडिंग के बारे में जानकारी रखें, इसलिए यदि आवश्यक हो तो encodingआश्चर्य से बचने के लिए पैरामीटर पास करें ।

अजगर 2 में

str8-बिट वैल्यूज़ unicodeके सीक्वेंस होते हैं , जबकि यूनिकोड के कैरेक्टर्स के सीक्वेंस होते हैं। ध्यान में रखने की एक बात यह है कि strऔर unicodeऑपरेटरों के साथ इस्तेमाल किया जा सकता है, तो strकेवल 7 बिट एएससीआई वर्ण होते हैं।

यह सहायक कार्यों का उपयोग करने के लिए के बीच परिवर्तित करने के लिए उपयोगी हो सकता है strऔर unicodeअजगर 2 में, और के बीच bytesऔर strअजगर 3 में।


4

से यूनिकोड क्या है :

मौलिक रूप से, कंप्यूटर केवल संख्याओं से निपटते हैं। वे हर एक के लिए एक नंबर निर्दिष्ट करके अक्षर और अन्य वर्ण संग्रहीत करते हैं।

......

यूनिकोड हर चरित्र के लिए एक विशिष्ट संख्या प्रदान करता है, चाहे कोई भी मंच हो, चाहे वह कोई भी कार्यक्रम हो, चाहे वह कोई भी भाषा हो।

इसलिए जब एक कंप्यूटर एक स्ट्रिंग का प्रतिनिधित्व करता है, तो यह स्ट्रिंग के कंप्यूटर में उनके अद्वितीय यूनिकोड नंबर के माध्यम से संग्रहीत वर्णों को पाता है और इन आंकड़ों को मेमोरी में संग्रहीत किया जाता है। लेकिन आप स्ट्रिंग को डिस्क पर सीधे लिखने या उनके यूनिकोड नंबर के माध्यम से नेटवर्क पर प्रसारित करने के लिए नहीं लिख सकते हैं क्योंकि ये आंकड़े केवल साधारण दशमलव संख्या हैं। आपको स्ट्रिंग को बाइट स्ट्रिंग में सांकेतिक शब्दों में बदलना चाहिए, जैसे कि UTF-8UTF-8एक वर्ण एन्कोडिंग है जो सभी संभावित वर्णों को एन्कोडिंग करने में सक्षम है और यह वर्णों को बाइट्स के रूप में संग्रहीत करता है (यह इस तरह दिखता है )। तो एन्कोडेड स्ट्रिंग को हर जगह इस्तेमाल किया जा सकता है क्योंकि हर जगह UTF-8लगभग समर्थित है। जब आप कोई पाठ फ़ाइल खोलते हैं, तो उसमें एन्कोड किया गया होता हैUTF-8अन्य प्रणालियों से, आपका कंप्यूटर इसे डिकोड करेगा और अपने विशिष्ट यूनिकोड नंबर के माध्यम से इसमें वर्ण प्रदर्शित करेगा। जब कोई ब्राउज़र UTF-8नेटवर्क से एन्कोडेड स्ट्रिंग डेटा प्राप्त करता है , तो यह डेटा को स्ट्रिंग ( UTF-8एन्कोडिंग में ब्राउज़र को मान लेना ) को डिकोड करेगा और स्ट्रिंग प्रदर्शित करेगा।

Python3 में, आप स्ट्रिंग और बाइट स्ट्रिंग को एक दूसरे में बदल सकते हैं:

>>> print('中文'.encode('utf-8'))
b'\xe4\xb8\xad\xe6\x96\x87'
>>> print(b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8'))
中文 

एक शब्द में, स्ट्रिंग को कंप्यूटर पर पढ़ने के लिए मनुष्यों को प्रदर्शित करने के लिए है और बाइट स्ट्रिंग डिस्क और डेटा ट्रांसमिशन के लिए भंडारण के लिए है।


1

यूनिकोड वर्णों के द्विआधारी निरूपण और विभिन्न प्रकार के स्वरूपण (जैसे लोअर केस / अपर केस, नई लाइन, कैरिज रिटर्न), और अन्य "चीजों" (जैसे इमोजीस) के लिए एक सहमत-प्रारूप प्रारूप है। एक कंप्यूटर यूनिकोड प्रतिनिधित्व (बिट्स की एक श्रृंखला) को संग्रहित करने में कम सक्षम नहीं है, चाहे वह मेमोरी में या किसी फ़ाइल में हो, जैसे कि वह आस्की प्रतिनिधित्व (बिट्स की एक अलग श्रृंखला), या किसी अन्य प्रतिनिधित्व (बिट्स की श्रृंखला) को संग्रहीत करने से है। )।

संचार के लिए संचार के लिए, पार्टियों को इस बात पर सहमत होना चाहिए कि प्रतिनिधित्व का क्या उपयोग किया जाएगा।

क्योंकि यूनिकोड अंतर-मानव और अंतर-कंप्यूटर संचार में उपयोग किए जाने वाले सभी संभावित पात्रों (और अन्य "चीजों") का प्रतिनिधित्व करना चाहता है , इसके लिए प्रतिनिधित्व की अन्य प्रणालियों की तुलना में कई पात्रों (या चीजों) के प्रतिनिधित्व के लिए अधिक से अधिक बिट्स की आवश्यकता होती है जो पात्रों / चीजों के अधिक सीमित सेट का प्रतिनिधित्व करना चाहते हैं। "सरल बनाने," और शायद ऐतिहासिक उपयोग को समायोजित करने के लिए, यूनिकोड प्रतिनिधित्व लगभग विशेष रूप से फ़ाइलों के पात्रों के भंडारण के उद्देश्य के लिए प्रतिनिधित्व (जैसे एससीआई) की किसी अन्य प्रणाली में परिवर्तित हो जाता है।

यह मामला है कि यूनिकोड नहीं है नहीं कर सकते हैं फ़ाइलों में पात्रों के भंडारण, या के माध्यम से उन्हें संचारित करने के लिए इस्तेमाल किया जा किसी भी संचार चैनल के लिए, बस यह है कि यह है नहीं।

शब्द "स्ट्रिंग," ठीक से परिभाषित नहीं है। "स्ट्रिंग," अपने सामान्य उपयोग में, वर्णों / चीजों के एक सेट को संदर्भित करता है। एक कंप्यूटर में, उन पात्रों को कई अलग-अलग बिट-बाय-बिट अभ्यावेदन में से किसी एक में संग्रहीत किया जा सकता है। "बाइट स्ट्रिंग" एक प्रतिनिधित्व का उपयोग करके संग्रहीत वर्णों का एक सेट है जो आठ बिट्स (आठ बिट्स को बाइट के रूप में संदर्भित किया जाता है) का उपयोग करता है। चूंकि, इन दिनों, कंप्यूटर यूनिकोड सिस्टम (बाइट्स की एक वेरिएबल संख्या द्वारा दर्शाए गए वर्ण) का उपयोग मेमोरी में कैरेक्टर को स्टोर करने के लिए करते हैं, और बाइट स्ट्रिंग्स (सिंगल बाइट्स द्वारा दर्शाए गए कैरेक्टर) को कैरेक्टर्स को फाइलों में स्टोर करने के लिए, एक कैरेक्टर का प्रतिनिधित्व करने से पहले रूपांतरण का उपयोग करना चाहिए। स्मृति में फ़ाइलों में भंडारण में ले जाया जाएगा।


0

चलो एक सरल एक-वर्ण स्ट्रिंग है 'š'और इसे बाइट्स के अनुक्रम में एनकोड करते हैं:

>>> 'š'.encode('utf-8')
b'\xc5\xa1'

इस उदाहरण के प्रयोजन के लिए आइए बाइट्स के अनुक्रम को अपने द्विआधारी रूप में प्रदर्शित करें:

>>> bin(int(b'\xc5\xa1'.hex(), 16))
'0b1100010110100001'

अब आम तौर पर जानकारी को डिकोड करना संभव नहीं है बिना यह जाने कि यह कैसे एनकोड किया गया था। केवल अगर आप जानते हैं कि utf-8पाठ एन्कोडिंग का उपयोग किया गया था, तो आप utf-8 को डिकोड करने के लिए एल्गोरिथ्म का पालन कर सकते हैं और मूल स्ट्रिंग प्राप्त कर सकते हैं:

11000101 10100001
   ^^^^^   ^^^^^^
   00101   100001

आप बाइनरी नंबर 101100001को एक स्ट्रिंग के रूप में प्रदर्शित कर सकते हैं :

>>> chr(int('101100001', 2))
'š'

0

पायथन भाषाओं में शामिल हैं strऔर bytesमानक "अंतर्निहित प्रकार" के रूप में। दूसरे शब्दों में, वे दोनों वर्ग हैं। मुझे नहीं लगता कि यह सार्थक है कि पायथन को इस तरह क्यों लागू किया गया है।

कहा जा रहा है कि, strऔर bytesएक दूसरे के समान हैं। दोनों एक ही तरीके से अधिकांश साझा करते हैं। निम्न विधियाँ strकक्षा के लिए अद्वितीय हैं :

casefold
encode
format
format_map
isdecimal
isidentifier
isnumeric
isprintable

निम्न विधियाँ bytesकक्षा के लिए अद्वितीय हैं :

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