2010-03-25 8 views
8

में तारों को पूल किया गया है क्या पाइथन के पास सभी तारों का एक पूल है और क्या वे वहां (तार) सिंगलेट हैं?पाइथन

a = str(num) 
b = str(num) 

:

अधिक सटीक, निम्नलिखित कोड में एक या दो तार स्मृति में बनाया गया था?

+4

बस संदर्भ के लिए, तार सिंगलेट नहीं हो सकते हैं। एक सिंगलटन एक वर्ग है जिसके लिए केवल एक उदाहरण हो सकता है, और वह उदाहरण वैश्विक स्तर पर पहुंच योग्य होना चाहिए। 'उम्मीद है)' str' वर्ग के कई उदाहरण हो सकते हैं; इसलिए यह एक सिंगलटन नहीं है। – zneak

+10

जिस अवधारणा को आप ढूंढ रहे हैं वह स्ट्रिंग इंटर्निंग है: http://en.wikipedia.org/wiki/String_interning –

+0

@zneak टिप्पणी के लिए धन्यवाद। मेरा मतलब वैल्यू-सिंगलटन जैसे कुछ था (पूल या स्ट्रिंग इंटर्निंग इसके लिए सही शब्द है - http://en.wikipedia.org/wiki/String_interning)। –

उत्तर

16

स्ट्रिंग्स अजगर में अडिग हैं, इसलिए कार्यान्वयन तय कर सकते हैं कि अक्सर के साथ सी # जुड़े एक शब्द है कि क्या प्रशिक्षु के लिए (, जिसका अर्थ है कि कुछ तार पूल में संग्रहीत होते हैं) तार या नहीं।

आपके उदाहरण में, आप गतिशील रूप से तार बना रहे हैं। CPython हमेशा यह पता लगाने के लिए पूल में नहीं दिखता है कि स्ट्रिंग पहले से मौजूद है या नहीं - यह भी समझ में नहीं आता है क्योंकि आपको स्ट्रिंग बनाने के लिए पहले स्मृति को आरक्षित करना होगा, और उसके बाद पूल सामग्री (अक्षम लंबे तारों के लिए)।

लेकिन लंबाई 1 के तार, CPython पूल पर गौर (सीएफ "stringobject.c") करता है के लिए: जब निरंतर तार का उपयोग कर

a = str(num) 
b = str(num) 
print a is b # <-- this will print False in most cases (but try str(1) is str(1)) 

लेकिन:

static PyStringObject *characters[UCHAR_MAX + 1]; 

... 

PyObject * 
PyString_FromStringAndSize(const char *str, Py_ssize_t size) 
{ 

... 

    if (size == 1 && str != NULL && 
    (op = characters[*str & UCHAR_MAX]) != NULL) 
    { 
     #ifdef COUNT_ALLOCS 
      one_strings++; 
     #endif 

     Py_INCREF(op); 
     return (PyObject *)op; 
    } 

... 

तो सीधे आपके कोड में, सीपीथॉन एक ही स्ट्रिंग उदाहरण का उपयोग करता है:

a = "text" 
b = "text" 
print a is b # <-- this will print True 
+0

@Andidog: यदि सीपीथॉन पूल में नहीं देखता है यह जांचने के लिए कि स्ट्रिंग पहले से मौजूद है या नहीं, तो प्रिंट बी क्यों प्रिंट करता है जब संख्या 5 के बराबर होती है? – Brian

+0

@ ब्रायन: क्षमा करें, यह थोड़ा गलत था। सीपीथॉन ने जिस तरह से लागू किया है, उसे समझाने के लिए मेरा जवाब संपादित किया। – AndiDog

+3

अच्छा जवाब। एकमात्र विस्तार जो मैं जोड़ता हूं वह यह ध्यान रखना है कि पायथन में 'intern()' – keturn

1

स्ट्रिंग सामान्य रूप से इंटर्न नहीं होते हैं। आपके उदाहरण में दो तार बनाए जाएंगे (0 और 9 के बीच मानों के अपवाद के साथ)। यह परीक्षण करने के हम देखना is ऑपरेटर का उपयोग कर सकते हैं दो तार एक ही वस्तु हैं:

>>> str(1056) is str(1056) 
False 
+1

क्या इस बारे में: [1] में: एक्स = str (5) में [2]: y = str (5) [3]: आईडी (एक्स) आउट [3]: 3077925280L में [4]: ​​आईडी (वाई) आउट [4]: ​​3077925280 एल ? – gruszczy

+0

gruszczy: यह एक अच्छा सवाल है। यह एक विशेष मामला है जो केवल 0 से 9 तक लागू होता है।सामान्य रूप से, कथन सत्य नहीं है। मैंने अपना जवाब स्पष्ट कर दिया है। –

+0

0 से 9 एक विशिष्ट संकलक पर एक विशिष्ट मामला है (हालांकि स्वीकार्य रूप से, यह संकलक अधिकांश लोग उपयोग करते हैं)। अन्य कंपाइलर प्री-डिफ़ाइंड स्ट्रिंग्स की एक अलग संख्या चुन सकते हैं। – Brian

5

सामान्य में, तार अजगर में प्रशिक्षु नहीं कर रहे हैं, लेकिन वे कभी कभी होने लगते है:

>>> str(5) is str(5) 
True 
>>> str(50) is str(50) 
False 

यह अजगर, जहां आम वस्तुओं तरीकों से अनुकूलित किया जा सकता है में असामान्य नहीं है कि असामान्य लोगों नहीं हैं:

>>> int(5+0) is int(5+0) 
True 
>>> int(50+0) is int(50+0) 
True 
>>> int(500+0) is int(500+0) 
False 

और ध्यान रखें, इन सभी प्रकार के विवरण पायथन के कार्यान्वयन और यहां तक ​​कि उसी कार्यान्वयन के संस्करणों के बीच भी भिन्न होंगे।