क्या वास्तव में "यू" और "आर" स्ट्रिंग झंडे करते हैं, और कच्चे स्ट्रिंग शाब्दिक क्या हैं?


652

यह सवाल पूछते हुए , मुझे एहसास हुआ कि मुझे कच्चे तार के बारे में ज्यादा जानकारी नहीं है। एक Django ट्रेनर होने का दावा करने वाले किसी व्यक्ति के लिए, यह बेकार है।

मुझे पता है कि एक एन्कोडिंग क्या है, और मुझे पता है कि u''अकेले क्या करता है क्योंकि मुझे यूनिकोड है।

  • लेकिन r''वास्तव में क्या करता है? यह किस प्रकार की स्ट्रिंग में परिणत होता है?

  • और सबसे बढ़कर, बिल्ली क्या करती ur''है?

  • अंत में, यूनिकोड स्ट्रिंग से एक साधारण कच्चे स्ट्रिंग पर वापस जाने का कोई विश्वसनीय तरीका है?

  • आह, और वैसे, यदि आपका सिस्टम और आपका टेक्स्ट एडिटर चारसेट UTF-8 में सेट है, तो क्या u''वास्तव में कुछ होता है?

जवाबों:


683

वास्तव में कोई भी "कच्चा तार " नहीं है; कच्चे स्ट्रिंग शाब्दिक हैं , जो 'r'शुरुआती उद्धरण से पहले चिह्नित स्ट्रिंग शाब्दिक हैं ।

"कच्चे स्ट्रिंग शाब्दिक" एक स्ट्रिंग शाब्दिक के लिए थोड़ा अलग वाक्यविन्यास है, जिसमें एक बैकस्लैश, का \अर्थ "बस एक बैकस्लैश" लिया जाता है (सिवाय इसके कि जब यह ठीक एक उद्धरण से पहले आता है जो अन्यथा शाब्दिक रूप से समाप्त हो जाएगा - नहीं newlines, tabs, backspaces, form-feed इत्यादि का प्रतिनिधित्व करने के लिए "एस्केप सीक्वेंस"। सामान्य स्ट्रिंग शाब्दिकों में, प्रत्येक बैकस्लैश को दोगुना किया जाना चाहिए ताकि बचने के क्रम के प्रारंभ के रूप में लिया जा सके।

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

r'...'एक बाइट स्ट्रिंग (में अजगर 2. *), है ur'...'एक यूनिकोड स्ट्रिंग (फिर से, पायथन में 2. *) है, और के हवाले के अन्य तीन प्रकार के किसी भी भी बिल्कुल तार के एक ही प्रकार का उत्पादन (तो उदाहरण के लिए r'...', r'''...''', r"...", r"""..."""सभी बाइट स्ट्रिंग्स हैं, और इसी तरह)।

यह निश्चित नहीं है कि " वापस जाने" से आपका क्या मतलब है - कोई आंतरिक रूप से पीछे और आगे की दिशा नहीं है, क्योंकि कोई कच्चा स्ट्रिंग प्रकार नहीं है , यह पूरी तरह से सामान्य स्ट्रिंग ऑब्जेक्ट, बाइट या यूनिकोड को व्यक्त करने के लिए एक वैकल्पिक वाक्यविन्यास है जैसा कि वे हो सकते हैं।

और हाँ, में अजगर 2. *, u'...' है पाठ्यक्रम हमेशा की बस से अलग '...', बाद एक बाइट स्ट्रिंग है पूर्व एक यूनिकोड स्ट्रिंग है -। शाब्दिक में एन्कोडिंग क्या व्यक्त किया जा सकता है यह एक पूरी तरह से रूढ़िवादी मुद्दा है।

जैसे, विचार करें (पायथन 2.6):

>>> sys.getsizeof('ciao')
28
>>> sys.getsizeof(u'ciao')
34

निश्चित रूप से यूनिकोड ऑब्जेक्ट अधिक मेमोरी स्पेस लेता है (बहुत छोटा स्ट्रिंग के लिए बहुत छोटा अंतर, जाहिर है; ;-)


6
"आर" को समझना किसी भी प्रकार या एन्कोडिंग मुद्दों का मतलब नहीं है, यह बहुत सरल है।
ई-सतीस

23
ध्यान दें कि ru "C: \ foo \ unstable" विफल हो जाएगा क्योंकि \ u एक यूनिकोड एस्केप अनुक्रम है आरयू मोड में। r मोड में \ u नहीं है
कर्टिस येलोप

26
ध्यान दें कि uऔर rसराहनीय नहीं हैं: ur'str'काम करता है, ru'str'नहीं। (कम से कम ipython में 2.7.2 win7 पर)
रफीK

7
बस rस्ट्रिंग्स का परीक्षण किया और देखा कि यदि \ अंतिम चरित्र है तो इसे शाब्दिक के रूप में नहीं लिया जाएगा, बल्कि इसके बजाय समापन उद्धरण से बच जाता है, जिससे SyntaxError: EOL while scanning string literal। तो \\ अभी भी \ बैकस्लैश के साथ समाप्त होने वाले किसी भी तार में अंतिम उदाहरण के लिए उपयोग किया जाना चाहिए ।
14 सितंबर को एंटलफॉर्मफॉर्म

1
अजगर 3.x - sys.getsizeof('cioa') == sys.getsizeof(r'cioa') == sys.getsizeof(u'cioa')(यूटीएफ 8 लैंग के साथ उबंटू 16.04)। इसी तरह, type('cioa') == type(r'cioa') == type(u'cioa')। लेकिन, कच्चे स्ट्रिंग प्रक्षेप से फर्क पड़ता है, इसलिएsys.getsizeof('\ncioa') == sys.getsizeof(u'\ncioa') != sys.getsizeof(r'\ncioa')
डैरेन वेबर

177

अजगर में दो प्रकार के स्ट्रिंग होते हैं: पारंपरिक strप्रकार और नए unicodeप्रकार। यदि आप uसामने बिना स्ट्रिंग स्ट्रिंग शाब्दिक लिखते हैं, तो आपको पुराना strप्रकार मिलता है जो 8-बिट वर्णों को संग्रहीत करता है, और uसामने वाले के साथ आपको नया unicodeप्रकार मिलता है जो किसी भी यूनिकोड चरित्र को संग्रहीत कर सकता है।

प्रकार rबिल्कुल नहीं बदलता है, यह सिर्फ बदलता है कि स्ट्रिंग शाब्दिक व्याख्या कैसे की जाती है। बिना rबैकस्लैश के बच पात्रों के रूप में व्यवहार किया जाता है। rबैकस्लैश के साथ , शाब्दिक के रूप में व्यवहार किया जाता है। किसी भी तरह, प्रकार समान है।

ur बेशक एक यूनिकोड स्ट्रिंग है जहां बैकस्लैश शाब्दिक बैकस्लैश हैं, एस्केप कोड का हिस्सा नहीं है।

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


धन्यवाद, स्वीकार किया। जैसा कि मैंने कहा, मुझे पता है कि यूनिकोड क्या है, मुझे नहीं पता था कि "आर" का क्या मतलब है और "यू" और "आर" का संयोजन क्या होगा। मुझे बेहतर पता है, चीयर्स।
ई-शनि

6
बैकस्लैश को कच्चे स्ट्रिंग लीटर में शाब्दिक रूप से नहीं माना जाता है, यही कारण r"\"है कि एक वाक्यविन्यास त्रुटि है।

4
केवल पायथन 2 पर लागू होता है
पॉलमैक्स

60

'रॉ स्ट्रिंग' का मतलब है कि यह दिखाई देते ही संग्रहित हो जाता है। उदाहरण के लिए, भागने के बजाय '\'सिर्फ एक बैकस्लैश है


3
... जब तक यह स्ट्रिंग का अंतिम चरित्र नहीं है, तब तक यह बंद होने वाले भाव से बच जाता है।
18

36

एक "यू" उपसर्ग दर्शाता है मान के unicodeबजाय टाइप होता है str

एक "आर" उपसर्ग के साथ कच्चे स्ट्रिंग शाब्दिक, उनके भीतर किसी भी भागने के अनुक्रम से बचते हैं, इसलिए len(r"\n")यह है 2. क्योंकि वे बच क्रम से बचते हैं, आप एक स्ट्रिंग शाब्दिक को एक बैकस्लैश के साथ समाप्त नहीं कर सकते हैं: यह एक वैध भागने अनुक्रम (जैसे r"\") नहीं है।

"रॉ" प्रकार का हिस्सा नहीं है, यह मूल्य का प्रतिनिधित्व करने का केवल एक तरीका है। उदाहरण के लिए, "\\n"और r"\n"जैसे समान मान होते हैं, 32, 0x20, और 0b100000समान हैं।

आपके पास यूनिकोड कच्चा स्ट्रिंग शाब्दिक हो सकता है:

>>> u = ur"\n"
>>> print type(u), len(u)
<type 'unicode'> 2

स्रोत फ़ाइल एन्कोडिंग सिर्फ यह निर्धारित करती है कि स्रोत फ़ाइल की व्याख्या कैसे की जाए, यह अन्यथा भावों या प्रकारों को प्रभावित नहीं करता है। हालाँकि, यह कोड से बचने के लिए अनुशंसित है जहाँ ASCII के अलावा अन्य एन्कोडिंग का अर्थ बदल जाएगा:

ASCII (या UTF-8, पायथन 3.0 के लिए) का उपयोग करने वाली फ़ाइलों में कोडिंग कुकी नहीं होनी चाहिए। लैटिन -1 (या UTF-8) का उपयोग केवल तब किया जाना चाहिए जब एक टिप्पणी या डॉकस्ट्रिंग को एक लेखक के नाम का उल्लेख करने की आवश्यकता होती है जिसे लैटिन -1 की आवश्यकता होती है; अन्यथा, \ x, \ u या \ U का उपयोग करना स्ट्रिंग स्ट्रिंग में गैर-एएससीआईआई डेटा को शामिल करने का पसंदीदा तरीका है।


30

मुझे इसे सरल रूप से समझाएं: अजगर 2 में, आप स्ट्रिंग को 2 अलग-अलग प्रकारों में संग्रहीत कर सकते हैं।

पहले एक ASCII है जो कि अजगर में स्ट्रै टाइप है, यह 1 बाइट मेमोरी का उपयोग करता है। (256 अक्षर, ज्यादातर अंग्रेजी वर्णमाला और सरल प्रतीकों को संग्रहीत करेंगे)

दूसरा प्रकार UNICODE है जो कि अजगर में यूनिकोड प्रकार है। यूनिकोड सभी प्रकार की भाषाओं को संग्रहीत करता है।

डिफ़ॉल्ट रूप से, अजगर स्ट्र प्रकार को पसंद करेगा, लेकिन यदि आप यूनिकोड प्रकार में स्ट्रिंग को स्टोर करना चाहते हैं, तो आप यू को टेक्स्ट के सामने रख सकते हैं जैसे 'u'text' या आप यूनिकोड ('टेक्स्ट') कॉल करके ऐसा कर सकते हैं

तो यू बस एक छोटी तरह से कलाकारों को समारोह कॉल करने के लिए है str को यूनिकोड । बस!

अब r भाग, आपने इसे कंप्यूटर को बताने के लिए पाठ के सामने रखा है कि पाठ कच्चा पाठ है, बैकस्लैश बचने का पात्र नहीं होना चाहिए। r '\ n' एक नई पंक्ति वर्ण नहीं बनाएगा। यह सिर्फ सादा पाठ है जिसमें 2 वर्ण हैं।

अगर आप str को यूनिकोड में बदलना चाहते हैं और वहां कच्चा पाठ भी डालना चाहते हैं , तो उर का उपयोग करें क्योंकि आरयू एक त्रुटि पैदा करेगा।

अब, महत्वपूर्ण हिस्सा:

आप r का उपयोग करके एक बैकस्लैश को स्टोर नहीं कर सकते , यह एकमात्र अपवाद है। तो यह कोड त्रुटि उत्पन्न करेगा: r '\'

बैकस्लैश (केवल एक) को स्टोर करने के लिए आपको '\\' का उपयोग करना होगा

यदि आप 1 से अधिक वर्ण संग्रहीत करना चाहते हैं, तो आप अभी भी r का उपयोग कर सकते हैं जैसे कि '\\' आपकी अपेक्षा के अनुसार 2 बैकस्लैश उत्पन्न करेगा।

मैं कारण नहीं जानता कि क्यों r एक बैकस्लैश स्टोरेज के साथ काम नहीं करता है, लेकिन इसका कारण अभी तक किसी ने नहीं बताया है। मुझे उम्मीद है कि यह एक बग है।


9
आप नोटिस करेंगे न केवल r'\'अवैध है, आप '\'किसी भी स्ट्रिंग की पूंछ पर एक भी नहीं डाल सकते । जैसे r'xxxxxx\'एक अवैध तार है।
गोताखोर

अजगर 3 के बारे में क्या?
कृष

1
@ क्रिस सभी अजगर 3 तार यूनिकोड समर्थित हैं। इसका प्रकार होगा str। यहाँ बेहतर समझ के लिए और पढ़ें: medium.com/better-programming/…
off99555

4

शायद यह स्पष्ट है, शायद नहीं, लेकिन आप x = chr (92) को कॉल करके स्ट्रिंग '\' बना सकते हैं

x=chr(92)
print type(x), len(x) # <type 'str'> 1
y='\\'
print type(y), len(y) # <type 'str'> 1
x==y   # True
x is y # False

4
x is ypython3 में True का मूल्यांकन करता है?
हबीब परवाद

5
@ हबीबपेरवाड, जो कि स्ट्रिंग इंटर्निंग के कारण है । आपको इस तथ्य पर कभी भी भरोसा नहीं करना चाहिए कि इंटर्निंग के कारण x is yमूल्यांकन होता है True। इसके बजाय उपयोग करें x == y(यदि आपकी जाँच नहीं हो रही है कि क्या x और y एक ही मेमोरी पोजीशन पर एक ही वस्तु है, जो है)।
लुकुब्रेटर

4

यूनिकोड स्ट्रिंग लिटरल

यूनिकोड स्ट्रिंग शाब्दिक (उपसर्गों द्वारा उपजी स्ट्रिंग u) का उपयोग अब पायथन 3 में नहीं किया जाता है। वे अभी भी मान्य हैं लेकिन सिर्फ पायथन 2 के साथ संगतता उद्देश्यों के लिए

कच्चे स्ट्रिंग शाब्दिक

यदि आप एक स्ट्रिंग शाब्दिक बनाना चाहते हैं जिसमें केवल आसानी से टाइप किए जाने वाले अक्षर जैसे अंग्रेजी अक्षर या संख्याएं हैं, तो आप उन्हें टाइप कर सकते हैं 'hello world':। लेकिन अगर आप कुछ और विदेशी पात्रों को भी शामिल करना चाहते हैं, तो आपको कुछ वर्कअराउंड का उपयोग करना होगा। वर्कअराउंड में से एक एस्केप सीक्वेंस हैं । इस तरह आप उदाहरण के लिए अपने स्ट्रिंग में एक नई लाइन का प्रतिनिधित्व कर सकते हैं बस \nअपने स्ट्रिंग शाब्दिक में दो आसानी से टाइप करने योग्य वर्ण जोड़कर । इसलिए जब आप 'hello\nworld'स्ट्रिंग को प्रिंट करेंगे, तो शब्द अलग-अलग लाइनों पर मुद्रित होंगे। यह बहुत आसान है!

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

'New updates are ready in c:\windows\updates\new'
'In this lesson we will learn what the \n escape sequence does.'

ऐसी स्थितियों में आप rइस तरह से चरित्र के साथ स्ट्रिंग शाब्दिक को उपसर्ग कर सकते हैं : r'hello\nworld'और पायथन द्वारा कोई भी अनुगामी अनुक्रम की व्याख्या नहीं की जाएगी। जैसे ही आपने इसे बनाया था स्ट्रिंग को प्रिंट किया जाएगा।

कच्चे स्ट्रिंग शाब्दिक शब्द "कच्चे" पूरी तरह से नहीं हैं?

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

एक स्ट्रिंग शाब्दिक की शाब्दिक परिभाषा से:

string     ::=  "'" stringitem* "'"
stringitem ::=  stringchar | escapeseq
stringchar ::=  <any source character except "\" or newline or the quote>
escapeseq  ::=  "\" <any source character>

यह स्पष्ट है कि स्ट्रिंग शाब्दिक (कच्चे या नहीं) जिसमें एक नंगे उद्धरण चरित्र होता है: 'hello'world'या बैकस्लैश के साथ समाप्त होता है: 'hello world\'मान्य नहीं हैं।

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