2009-09-08 11 views
53

पायथन में "hello" is "hello" == True क्यों है?पायथन: क्यों ("हैलो" "हैलो") सत्य के रूप में मूल्यांकन करता है?

मैं निम्नलिखित here पढ़ें:

तो दो स्ट्रिंग शाब्दिक बराबर हैं, वे एक ही स्मृति स्थान के लिए रखा गया है। एक स्ट्रिंग एक अपरिवर्तनीय इकाई है। कोई नुकसान नहीं हो सकता है।

तो प्रत्येक पायथन स्ट्रिंग के लिए स्मृति में एक और केवल एक स्थान है? बहुत अजीब लगता है। यहाँ क्या चल रहा है?

+0

इसके बजाय यहां देखें: http: //pyref.infogami।कॉम/इंटर्न – bzlm

+0

मेमोरी स्थानों की जांच के लिए 'id' फ़ंक्शन पर भी एक नज़र डालें:' प्रिंट आईडी ("हैलो") ' – Blixt

+0

bzlm, pyref.infogami.com/intern लिंक मर गया है, लेकिन archive.org में एक है यहां कॉपी करें:
http://web.archive.org/web/20090429040354/http://pyref.infogami.com/intern
हालांकि, हालांकि यह अक्सर सच है, यह हमेशा सत्य नहीं है, क्योंकि @ बॉबिन ने बहुत प्रदर्शन किया अच्छी तरह से नीचे। –

उत्तर

80

पायथन (जैसे जावा, सी, सी ++, .NET) स्ट्रिंग पूलिंग/इंटर्निंग का उपयोग करता है। दुभाषिया को पता चलता है कि "हैलो" "हैलो" जैसा ही है, इसलिए यह स्मृति में उसी स्थान को अनुकूलित और उपयोग करता है।

एक और goodie: "नरक" + "ओ" "हैलो" ==> यह सच है

+23

यहां तक ​​कि सी/सी ++ आमतौर पर ऐसा करते हैं; "foo" == "foo" सी में अक्सर सत्य होता है सी और पायथन दोनों में, यह एक कार्यान्वयन विवरण है; मुझे नहीं लगता कि पायथन में कुछ भी * आवश्यक है कि दुभाषिया ऐसा करता है, और सी/सी ++ में यह एक अनुकूलन है कि सभी कंपाइलर नहीं करते हैं और इसे अक्षम किया जा सकता है। (इसके विपरीत, यह संपत्ति * हमेशा * लुआ में सच है; सभी तारों को प्रशिक्षित किया जाता है।) –

+2

@Glenn, आप सही हैं और मुझे खुशी है कि किसी ने उल्लेख किया है। निश्चित रूप से किसी को भी इस पर सच होना चाहिए। – Triptych

+0

यह संकलन समय निर्धारित तारों को बनाकर इस अनुकूलन को करने के लिए सी/सी ++ विशिष्ट नौकरी जैसी भाषाओं के लिए एक दुभाषिया या संकलक है। – andy

1

यह अजीब क्यों है। यदि स्ट्रिंग अपरिवर्तनीय है तो इसे केवल एक बार स्टोर करने के लिए बहुत समझदारी होती है। .NET का एक ही व्यवहार है।

+1

स्ट्रिंग इंटर्निंग अपरिवर्तनीयता से संबंधित कैसे है? पाइथन और ".NET" दोनों में कई चीजें इंटर्न किए बिना अपरिवर्तनीय हैं। – bzlm

+1

क्योंकि अगर स्मृति में बदलने के लिए एक स्ट्रिंग अक्षर के लिए यह संभव था, तो इसे साझा नहीं किया जा सका (या "प्रशिक्षित")। – harto

+0

सच है, लेकिन तथ्य यह है कि वस्तु अपरिवर्तनीय है उदाहरण के संदर्भ के सुरक्षित साझाकरण की अनुमति देता है। –

2

अजगर दुभाषिया/संकलक स्ट्रिंग शाब्दिक, पात्रों में से अर्थात उद्धृत सूची को पार्स करता है। जब ऐसा होता है, तो यह पता लगा सकता है कि "मैंने पहले यह स्ट्रिंग देखी है", और पिछली बार उसी प्रस्तुति का उपयोग करें। ऐसा इसलिए हो सकता है क्योंकि यह जानता है कि इस तरह से परिभाषित तारों को बदला नहीं जा सकता है।

14

शाब्दिक तार शायद उनके हैश या कुछ समान के आधार पर समूहित किए जाते हैं। एक ही शाब्दिक तारों में से दो एक ही स्मृति में संग्रहीत किए जाएंगे, और किसी भी संदर्भ दोनों को संदर्भित किया जाएगा।

Memory  Code 
------- 
|   myLine = "hello" 
|  /
|hello < 
|  \ 
|   myLine = "hello" 
------- 
+2

यह वही है जो स्वीकृत उत्तर कहता है ... – Martin

+2

बुराई डाउनवॉट्स का सामना करने के लिए उपरोक्त – Martin

+4

+1: स्वीकृत उत्तर में अच्छा ASCII कला नहीं है :-) – kriss

6

is ऑपरेटर सत्य लौटाता है यदि दोनों तर्क एक ही वस्तु हैं। आपका परिणाम इसका परिणाम है, और उद्धृत बिट।

स्ट्रिंग अक्षर के मामले में, इन्हें प्रशिक्षित किया गया है, जिसका अर्थ है कि उनकी ज्ञात तारों की तुलना की जाती है। यदि एक समान स्ट्रिंग पहले ही ज्ञात है, तो शाब्दिक विकल्प के बजाय शाब्दिक वह मान लेता है। इस प्रकार, वे एक ही वस्तु बन जाते हैं, और अभिव्यक्ति सच है।

+0

वे "एक ही वस्तु बन जाते हैं"? यदि आप एक को संशोधित करते हैं, तो दूसरा संशोधित नहीं होता है। – endolith

+3

@endolith: प्रश्न में ऑब्जेक्ट आंतरिक स्ट्रिंग है, न कि उस स्ट्रिंग को आवंटित चर। स्ट्रिंग को संशोधित करने के लिए पाइथन में कोई रास्ता नहीं है। – SingleNegationElimination

57

तो प्रत्येक पायथन स्ट्रिंग के लिए स्मृति में एक और केवल एक स्थान है?

नहीं, केवल लोगों दुभाषिया अनुकूलन करने के लिए है, जो एक नीति है कि भाषा विनिर्देश का हिस्सा नहीं है और जो विभिन्न CPython संस्करणों में बदल सकता है आधार पर निर्णय है फैसला किया है।

उदाहरण के लिए। मेरे पर स्थापित (2.6.2 लिनक्स):

>>> 'X'*10 is 'X'*10 
True 
>>> 'X'*30 is 'X'*30 
False 
इसी तरह ints के लिए

:

>>> 2**8 is 2**8 
True 
>>> 2**9 is 2**9 
False 

तो 'स्ट्रिंग' पर भरोसा नहीं करते 'स्ट्रिंग' है: यहां तक ​​कि बस सी कार्यान्वयन इसे देख सुरक्षित नहीं है

+11

इस प्रकार, आपको हमेशा स्ट्रिंग समानता तुलना के लिए '==' का उपयोग करना चाहिए। – SingleNegationElimination

+0

पाइथन में इंटरप्रेटर छोटे पूर्णांक (256 तक) कैश करता है। तो, 'ए = 50; बी = 50; एक बी बी सच है, 'ए = 500; बी = 500; एक बी है झूठा है। –

0

मुझे लगता है कि यदि किसी भी दो चर (केवल स्ट्रिंग्स) में एक ही मान नहीं है, तो मान केवल एक बार दो बार संग्रहीत नहीं किया जाएगा और दोनों चर एक ही स्थान पर इंगित करेंगे। यह स्मृति बचाता है।

+0

सच नहीं है! यह केवल तार और छोटे पूर्णांक का सम्मान करता है। जब आप किसी सूची या शब्दकोश की एक प्रति बनाते हैं, उदाहरण के लिए, हालांकि उनके पास एक ही मान (== समानता) है, वे एक ही वस्तु नहीं हैं ("समानता" है)। यही कारण है कि आप सूची की प्रति बदल सकते हैं क्योंकि मूल अपरिवर्तित रहता है (या इसके विपरीत)। ओरेली द्वारा लर्निंग पायथन के डायनामिक टाइपिंग अध्याय में महान स्पष्टीकरण प्रदान किया गया है – fanny

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