python - क्या आईडी() का उपयोग करते समय[] और सूची() के बीच अंतर है?



list python-internals (1)

क्या कोई निम्नलिखित की व्याख्या कर सकता है?

आईडी समान क्यों है, लेकिन सूचियां अलग हैं?

>>> [] is []
False
>>> id([]) == id([])
True

क्या सूची निर्माण में अंतर है?

>>> id(list()) == id(list())
False
>>> id([]) == id([])
True

ये क्यों हो रहा है? मुझे दो अलग-अलग सूची मिली हैं। केवल एक, या तीन या अधिक क्यों नहीं?

>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x7fd2be868128>
>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x7fd2be868170>
>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x7fd2be868128>
>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x7fd2be868170>

आपने id() गलत उपयोग किया। id([]) किसी ऑब्जेक्ट की मेमोरी आईडी लेता है जिसे तुरंत छोड़ दिया जाता है । सब के बाद, कुछ भी नहीं संदर्भित कर रहा है एक बार id() इसके साथ किया जाता है। तो अगली बार जब आप id([]) उपयोग करते हैं तो पायथन को मेमोरी और लो और निहारने का फिर से उपयोग करने का अवसर दिखाई देता है, वे पते वास्तव में एक ही हैं।

हालाँकि, यह एक कार्यान्वयन विवरण है, जिस पर आप भरोसा नहीं कर सकते हैं, और यह हमेशा मेमोरी एड्रेस का पुनः उपयोग करने में सक्षम नहीं होगा।

ध्यान दें कि id() मूल्य केवल आजीवन के लिए अद्वितीय हैं, documentation देखें:

यह एक पूर्णांक है जो अपने जीवनकाल के दौरान इस वस्तु के लिए अद्वितीय और निरंतर होने की गारंटी है। गैर-अतिव्यापी जीवनकाल वाली दो वस्तुओं में एक ही id() मूल्य हो सकता है।

(बोल्ड जोर मेरा)।

वह id(list()) मेमोरी लोकेशन का फिर से उपयोग नहीं कर सकती है, अतिरिक्त फाल्ट म्यूटेशन के कारण होता है जो किसी फ़ंक्शन को कॉल करने के लिए स्टैक पर करंट फ्रेम को पुश करने के कारण होता है, फिर list() कॉल list() कॉल करने पर इसे फिर से पॉपिंग करता है।

दोनों [] और list() एक नई खाली सूची वस्तु का उत्पादन करते हैं; लेकिन आपको पहले उन अलग-अलग सूचियों (यहाँ और b ) के संदर्भ बनाने की आवश्यकता है:

>>> a, b = [], []
>>> a is b
False
>>> id(a) == id(b)
False
>>> a, b = list(), list()
>>> a is b
False
>>> id(a) == id(b)
False

जब आप [].__repr__ उपयोग करते हैं तो वही होता है। पायथन इंटरएक्टिव इंटरप्रेटर का एक विशेष वैश्विक नाम है, _ , जिसका उपयोग आप उत्पादित अंतिम परिणाम को संदर्भित करने के लिए कर सकते हैं:

>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x10e011608>
>>> _
<method-wrapper '__repr__' of list object at 0x10e011608>

यह एक अतिरिक्त संदर्भ बनाता है, इसलिए __repr__ विधि, और विस्तार से, इसके लिए आपके द्वारा बनाई गई खाली सूची अभी भी सक्रिय मानी जाती है । स्मृति स्थान को मुक्त नहीं किया गया है और आपके द्वारा बनाई गई अगली सूची के लिए उपलब्ध नहीं है।

लेकिन [].__repr__ फिर से निष्पादित करते हुए, पायथन अब _ को उस नई विधि ऑब्जेक्ट से बांधता है। अचानक पिछले __repr__ विधि को अब किसी भी चीज़ से संदर्भित नहीं किया जा सकता है और इसे मुक्त किया जा सकता है, और इसलिए सूची ऑब्जेक्ट है।

तीसरी बार जब आप निष्पादित करते हैं [].__repr__ पुन: उपयोग के लिए पहला मेमोरी लोकेशन फिर से उपलब्ध होता है, इसलिए पायथन सिर्फ इतना करता है:

>>> [].__repr__  # create a new method
<method-wrapper '__repr__' of list object at 0x10e00cb08>
>>> _            # now _ points to the new method
<method-wrapper '__repr__' of list object at 0x10e00cb08>
>>> [].__repr__  # so the old address can be reused
<method-wrapper '__repr__' of list object at 0x10e011608>

आप कभी भी दो से अधिक सूची नहीं बनाते हैं; पिछले एक (अभी भी _ द्वारा संदर्भित) और वर्तमान एक। यदि आप अधिक मेमोरी स्थान देखना चाहते हैं, तो अन्य संदर्भ जोड़ने के लिए चर का उपयोग करें।





python-internals