2017-02-10 4 views
5

dict.keys (और dict.items और dict.values समान रूप से) शब्दकोश ऑब्जेक्ट का एक दृश्य देता है, मुझे लगता है कि वास्तव में dict_keys पर हमें असर डालने वाले शब्दकोश को हटाने से हम उन्हें प्राप्त कर चुके हैं।मैंने अपना निर्देश हटा दिया, लेकिन मेरी dict_keys को कोई फर्क नहीं पड़ता, वह क्यों है?

सामान्य शब्दकोश के साथ

और यह कुंजी है:

del d 
i = iter(k) 
list(i) # works fine and prints the keys 

क्या किसी को पता है कि क्यों यह मामला है:

d = {i:i for i in range(20)} 
k = d.keys() # similarly with d.values and d.items 

जाहिर है, यह मामला नहीं है?

उत्तर

4

ऑब्जेक्ट पर d.keys() पर कॉल करने से बस शब्द वस्तु के लिए संदर्भ गणना बढ़ जाती है; del dd नाम से ऑब्जेक्ट के लिए कचरा कलेक्टर ट्रिगर नहीं करेगा क्योंकि संदर्भ हमेशा शून्य से बड़ा होगा।

आप शब्दकोश वस्तु वृद्धि के लिए संदर्भ गिनती देख सकते हैं जब d.keys()sys.getrefcount का उपयोग करके कहा जाता है:

Py_INCREF(dict); 
dv->dv_dict = (PyDictObject *)dict; 

यह किया है:

from sys import getrefcount 
d = {i:i for i in range(20)} 
getrefcount(d) # 2 
k = d.keys() 
getrefcount(d) # 3 (+1 due to d.keys()) 
कॉल दृश्य शब्दकोश इस reference increment can be seen निर्माण करती है कि में

ऑब्जेक्ट को ऑब्जेक्ट स्ट्रक्चर की इसी प्रविष्टि में संग्रहीत करने से ठीक पहले।

के बाद से एक दृश्य वास्तव में अंतर्निहित dict के लिए एक संदर्भ के साथ सिर्फ एक iterable वस्तु है, तो आप भी एक कदम गहराई में जाने और हटाने के अपने इटरेटर प्राप्त करने के बाद कुंजी पर आपत्ति है और अभी भी मूल्यों को प्राप्त करने की क्षमता है सकते हैं:

i = iter(k) # +1 reference 
del k, d 
next(i)  # 0 

iter(k) increases the reference count मूल शब्दकोश के लिए एक फिर से, ऑब्जेक्ट को संग्रह से दूर रखने के लिए।

+0

हाँ @AlexFung, इस अनुमति दी है जब आप (जो मैं अपना सर्वश्रेष्ठ करने की कोशिश करने के लिए) इसे ठीक करने के लिए सक्षम कर रहे हैं। यहां देखें [क्या मैं अपने प्रश्न का उत्तर दे सकता हूं?] (Http://stackoverflow.com/help/self-answer) –

+0

@ जिमफसारकिस-हिलियार्ड ठंडा। मुझे पता नहीं था कि तत्काल आत्म उत्तर को प्रोत्साहित किया जाता है –

9

del d हटाता चरd, लेकिन वस्तु यह अगर वहाँ अन्य संदर्भ हैं मौजूद रहेंगे को दर्शाता है कि। आप इस का पालन करने के लिए एक दृश्य शब्दकोश की जरूरत नहीं है: (। d['x']='x' लाइन को दर्शाता है dd=d करता है कि नहीं शब्दकोश स्वयं की कॉपी है, यह केवल एक अतिरिक्त संदर्भ बनाता है)

>>> d = {i:i for i in range(5)} 
>>> dd = d 
>>> d['x'] = 'x' 
>>> del d 
>>> d 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'd' is not defined 
>>> dd 
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 'x': 'x'} 

भी विपरीत clear के व्यवहार है, जो वास्तविक वस्तु को संशोधित करता है:

>>> d = {i:i for i in range(5)} 
>>> k = d.keys() 
>>> del d 
>>> list(k) 
[0, 1, 2, 3, 4] 

>>> d = {i:i for i in range(5)} 
>>> k = d.keys() 
>>> d.clear() 
>>> list(k) 
[] 
संबंधित मुद्दे