2013-03-27 21 views
5

आज मुझे पता चला कि अजगर अभिव्यक्ति {} कैश, और एक नया खाली dict जब यह एक चर के लिए निर्दिष्ट की के साथ यह बदल देता है:अजीब के स्पष्ट कैशिंग से संबंधित व्यवहार "{}"

print id({}) 
# 40357936 

print id({}) 
# 40357936 

x = {} 
print id(x) 
# 40357936 

print id({}) 
# 40356432 

मुझे नहीं है स्रोत कोड को देखा, लेकिन मुझे यह पता है कि यह कैसे कार्यान्वित किया जा सकता है। (हो सकता है कि जब वैश्विक {} के संदर्भ गिनती वृद्धि की जाती है, वैश्विक {} प्रतिस्थापित हो जाता है।)

लेकिन इस बिट पर विचार करें:

def f(x): 
    x['a'] = 1 
    print(id(x), x) 

print(id(x)) 
# 34076544 

f({}) 
# (34076544, {'a': 1}) 

print(id({}), {}) 
# (34076544, {}) 

print(id({})) 
# 34076544 

f के कारण यह बदला जाएगा बिना वैश्विक dict को संशोधित करता है, और यह संशोधित निर्देश मुद्रित करता है। लेकिन आईडी के बावजूद f के बाहर, वैश्विक निर्देश अब खाली है!

क्या हो रहा है ??

+0

आपको इसमें रुचि भी हो सकती है: http://stackoverflow.com/questions/15315096/why-the-id-of-an-object-would-change-depending-on-the-line-in-the -पिथन-खोल/15321863 # 15321863 – User

+0

बहुत अच्छा किनारा मामला, साझा करने के लिए धन्यवाद। – dimo414

+0

पाइथन की 'आईडी()' ऑब्जेक्ट्स के लिए एक आईडी के रूप में एक स्मृति पता (कम से कम CPython कार्यान्वयन में) का उपयोग करता है। यह केवल एक बिंदु पर एक अद्वितीय पहचानकर्ता है, जो आपके कार्यक्रम के पूरे जीवनकाल में अद्वितीय नहीं है। यह दस्तावेज़ीकरण में स्पष्ट है: http://docs.python.org/2/library/functions.html#id –

उत्तर

6

यह कैश नहीं किया जा रहा है - यदि आप कहीं भी {} का परिणाम निर्दिष्ट नहीं करते हैं, तो इसकी संदर्भ संख्या 0 है और इसे तुरंत साफ़ कर दिया गया है। यह अभी हुआ कि आपके द्वारा आवंटित अगले व्यक्ति को पुराने से स्मृति का पुन: उपयोग किया गया। जब आप इसे x पर असाइन करते हैं तो आप इसे जीवित रखते हैं, और उसके बाद अगला व्यक्ति का एक अलग पता होता है।

आपके फ़ंक्शन उदाहरण में, f रिटर्न में आपके नियम के लिए कोई शेष संदर्भ नहीं है, इसलिए यह भी साफ हो जाता है, और वही बात लागू होती है।

+0

ग्रेट उत्तर, यह बताते हुए कि "कैशिंग" (जिसे मैंने सोचा था कि एक काफी संदिग्ध अनुकूलन था, वैसे भी) – valtron

4

पायथन यहां कोई कैशिंग नहीं कर रहा है। वहाँ दो संभावनाएं जब id() एक कार्यक्रम में विभिन्न बिंदुओं पर एक ही वापसी मान देता हैं:

  1. id() एक ही वस्तु पर बुलाया गया था दो बार
  2. पहले उद्देश्य यह है कि id() पर कचरा दूसरी वस्तु से पहले एकत्र किया गया था बुलाया गया था बनाया गया था, और दूसरी वस्तु मूल

इस मामले में के रूप में ही स्मृति स्थान में बनाया गया था, यह दूसरा एक था। इसका मतलब यह है कि भले ही print id({}); print id({}) एक ही मान दो बार प्रिंट कर सकता है, प्रत्येक कॉल एक अलग वस्तु पर है।

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