2016-10-12 10 views
5

अजगर मेंपाइथन स्ट्रिंग को कैसे संग्रहीत करता है ताकि 'is' ऑपरेटर अक्षर पर काम करता है?

>>> a = 5 
>>> a is 5 
True 

लेकिन

>>> a = 500 
>>> a is 500 
False 

इसका कारण यह है कि यह एक ही पते के रूप में कम पूर्णांक संग्रहीत करता है। लेकिन एक बार जब संख्या जटिल हो जाती है, तो प्रत्येक int को अपना अनूठा पता स्थान मिलता है। मुझे यह अर्थपूर्ण लग रहा है।

वर्तमान कार्यान्वयन जब आप उस सीमा आप वास्तव में सिर्फ वापस मौजूदा ऑब्जेक्ट के लिए एक संदर्भ पाने में एक पूर्णांक बनाने के लिए, -5 और 256 के बीच सभी पूर्णांकों के लिए पूर्णांक ऑब्जेक्ट की श्रृंखला रहता है।

तो अब, यह तारों पर क्यों लागू नहीं होता है? तारों को बड़े पूर्णांक के रूप में जटिल नहीं हैं (यदि मोरेसो नहीं है)?

>>> a = '1234567' 
>>> a is '1234567' 
True 

पाइथन सभी स्ट्रिंग अक्षरों के लिए कुशलतापूर्वक समान पते का उपयोग कैसे करता है? यह संख्याओं के लिए हर संभव स्ट्रिंग की सरणी नहीं रख सकता है।

उत्तर

0

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

उदाहरण

के लिए जब आप कहते हैं a = 'foo', यह पहली स्ट्रिंग foo और चेक हैश अगर एक प्रविष्टि पहले से ही हैश तालिका में मौजूद है। यदि हां, तो परिवर्तनीय a अब उस पते का संदर्भ देता है।

यदि तालिका में कोई प्रविष्टि नहीं मिली है, तो पाइथन स्ट्रिंग को स्टोर करने के लिए स्मृति आवंटित करता है, foo हैश आवंटित स्मृति के पते के साथ तालिका में एक प्रविष्टि जोड़ता है।

देखें:

  1. How is the 'is' keyword implemented in Python?
  2. https://en.wikipedia.org/wiki/String_interning
+0

'is' तुलना ऑब्जेक्ट' id's –

+0

यह स्मृति पते की तुलना भी करता है। देखें http://stackoverflow.com/questions/2987958/how-is-the-is-keyword-implemented-in-python –

+1

आईडी == स्मृति पता सीपीथॉन आईआईआरसी में –

3

यह इंटर्निंग नामक एक अनुकूलन तकनीक है। सीपीथॉन equal values of string constants को पहचानता है और नए उदाहरणों के लिए अतिरिक्त मेमोरी आवंटित नहीं करता है, लेकिन यह उसी id() दोनों को देकर, केवल उसी (इंटर्न करता है) को इंगित करता है।

एक पुष्टि करते हैं कि केवल स्थिरांक इलाज कर रहे हैं इस तरह से (b की तरह साधारण संचालन पहचाने जाते हैं) के आसपास खेल सकते हैं:

# Two string constants 
a = "aaaa" 
b = "aa" + "aa" 

# Prevent interpreter from figuring out string constant 
c = "aaa" 
c += "a" 

print id(a)   # 4509752320 
print id(b)   # 4509752320 
print id(c)   # 4509752176 !! 

हालांकि आप मैन्युअल रूप से एक स्ट्रिंग मजबूर कर सकते हैं एक पहले से ही एक मौजूदा intern() उपयोग करने के लिए मैप किया :

c = intern(c) 

print id(a)   # 4509752320 
print id(b)   # 4509752320 
print id(c)   # 4509752320 !! 

अन्य दुभाषिया इसे अलग-अलग कर सकते हैं। चूंकि तार अपरिवर्तनीय हैं, दोनों में से एक को बदलना दूसरे को नहीं बदलेगा।

+0

यह पूर्वनिर्धारित पूर्णांकों की सीमा की तरह लग रहा -5 +256 है। लगता है कि सभी अन्य लोगों को फर्श पर फ्लाई पर बनाया गया है, इसलिए "है" झूठा रिटर्न। –

+0

उत्तर के रूप में चिह्नित नहीं किया गया क्योंकि आप "इसकी अनुकूलन" कहते हैं लेकिन यह नहीं समझाते कि इसे कैसे संग्रहीत किया जा रहा है, जो सवाल है। या अन्य शब्दों में वे अनुकूलन कैसे कर रहे हैं। –

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