यह Python2.7 जो बहुत अच्छी तरह से लिखा गया है और पढ़ने के लिए स्पष्ट है के लिए स्रोत कोड को पढ़ने के लिए मजेदार है। (यदि आप घर पर खेलना चाहते हैं तो मैं संस्करण 2.7.12 का जिक्र कर रहा हूं।) कोड को समझने के लिए एक अच्छी जगह व्याख्यान की उत्कृष्ट श्रृंखला है: C Python Internals जो शुरुआती परिप्रेक्ष्य से शुरू होती है।
हमारे लिए प्रासंगिक महत्वपूर्ण कोड (सी में लिखा गया) फ़ाइल 'ऑब्जेक्ट्स/intobject.c' में दिखाई देता है (मैंने कुछ #ifdef कोड हटा दिया है और स्पष्टता के लिए एक नई इंटीजर ऑब्जेक्ट के निर्माण को थोड़ा संशोधित किया है):
#define NSMALLPOSINTS 257
#define NSMALLNEGINTS 5
static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
PyObject *
PyInt_FromLong(long ival)
{
register PyIntObject *v;
if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
v = small_ints[ival + NSMALLNEGINTS];
Py_INCREF(v);
return (PyObject *) v;
}
/* Inline PyObject_New */
v = (PyIntObject *)Py_TYPE(v);
PyObject_INIT(v, &PyInt_Type);
v->ob_ival = ival;
return (PyObject *) v;
}
तो अनिवार्य रूप से यह -5 256 करने के लिए समावेशी से सभी नंबरों को शामिल करते हुए एक पूर्व निर्धारित सरणी बनाता है और उन वस्तुओं यदि संभव हो तो (उनके संदर्भ Py_INCREF मैक्रो का उपयोग गिनती बढ़ रही है) का उपयोग करता है। यदि नहीं, तो यह एक नई नई PyInt_Type ऑब्जेक्ट बनाएगा, जिसे 1 की संदर्भ संख्या के साथ शुरू किया गया है।
रहस्य का मानना है कि प्रत्येक संख्या में संदर्भ संख्या 3 (वास्तव में लगभग कोई नई वस्तु) क्यों होती है, जब आप पाइथन उत्पन्न करते हैं तो बाइट कोड देखते हैं। वर्चुअल मशीन एक वैल्यू स्टैक (फर्थ में थोड़ा सा) के साथ काम करती है, और प्रत्येक बार जब ऑब्जेक्ट को स्टैक स्टैक पर रखा जाता है तो यह संदर्भ गणना में वृद्धि करता है।
तो मुझे क्या संदेह हो रहा है यह है कि आपका कोड स्वयं आपके द्वारा देखे जाने वाले सभी 3 संदर्भ प्रदान कर रहा है, क्योंकि संख्याओं के लिए छोटे मूल्यों की सूची में नहीं, आपको एक अद्वितीय वस्तु मिलनी चाहिए। पहला संदर्भ संभावित रूप से कॉलफैक के कॉलर के लिए मूल्य स्टैक में होता है जब यह कॉल करता है; दूसरा getrefcount फ्रेम के लिए स्थानीय चर सूची में है; तीसरा गेटफ्रैंट फ्रेम में वैल्यू स्टैक पर होने की संभावना है, जबकि यह इसकी संदर्भ संख्या को देखता है।
यदि आप इस मुद्दे में आगे बढ़ना चाहते हैं तो एक उपयोगी टूल 'compile' कमांड, और 'डिस' कमांड (डिससेम्बल) है जो 'डी' मॉड्यूल में है, जो आपको एक साथ वास्तविक पढ़ने की अनुमति देगा बाइट कोड पाइथन कोड के किसी भी टुकड़े से उत्पन्न होता है, और आपको यह पता लगाने में मदद करनी चाहिए कि तीसरा संदर्भ कब और कहाँ बनाया जा रहा है।
छोटे मानों के लिए उच्च संदर्भ गणना के लिए, जब आप पाइथन शुरू करते हैं, तो यह स्वचालित रूप से संपूर्ण मानक लाइब्रेरी लोड करता है और आपके कोड को समझने से पहले बहुत सारे पायथन मॉड्यूल प्रारंभिक कोड चलाता है। ये मॉड्यूल अपनी प्रतियां कई छोटे पूर्णांक (और कोई भी ऑब्जेक्ट जो अद्वितीय भी नहीं है) रखते हैं।
'sys.getrefcount (257) 'आज़माएं और यह शायद स्पष्ट रूप से गिर जाएगी। –
एक दिलचस्प संख्या के लिए 'sys.getrefcount (कोई नहीं) 'आज़माएं। – cdarke
वास्तव में अजीब बात है, मैंने कभी भी 257 के साथ एक var बनाया नहीं है। यह 3 क्यों वापस आता है? –