2012-05-04 9 views
22

यदि किसी शब्दकोश में म्यूटेबल ऑब्जेक्ट्स या कस्टम क्लासेस की ऑब्जेक्ट्स (एक क्वेरीसेट या एक डेटटाइम कहें) शामिल हैं, तो फिर इन ऑब्जेक्ट्स को स्मृति से हटाएं clear() पर कॉल करेंगे? क्या यह ताना और del के माध्यम से लूपिंग से अलग व्यवहार करता है?क्या शब्दकोश की स्पष्ट() विधि स्मृति से सभी आइटम संबंधित वस्तुओं को हटा देती है?

उदाहरण के लिए। पर विचार

class MyClass(object): 
    '''Test Class.''' 

my_obj_1 = MyClass() 
my_obj_2 = MyClass() 

my_dict = { 'foo' : my_obj_1, 'bar' : my_obj_2 } 

तो

my_dict.clear() 

for key in my_dict.keys(): 
    del my_dict[key] 

रूप

में ही है?

उत्तर

36

Python documentation on dicts कहा गया है कि del d[key] शब्दकोश से d[key] को हटा जबकि d.clear() हर कुंजी निकाल देता है, तो मूल रूप से उनके व्यवहार में ही है।

स्मृति समस्या पर, पायथन में जब आप "हटाएं" तो आप मूल रूप से किसी ऑब्जेक्ट का संदर्भ निकाल रहे हैं। जब किसी ऑब्जेक्ट को किसी भी चर या न ही अन्य ऑब्जेक्ट द्वारा संदर्भित किया जाता है या पहुंच योग्य नहीं होता है, तो यह कचरा बन जाता है और इसे स्मृति से हटाया जा सकता है। पायथन में एक कचरा कलेक्टर है जो समय-समय पर यह जांचने का यह काम करता है कि कौन सी वस्तुएं कचरा हैं और उनके लिए आवंटित स्मृति जारी करती हैं। यदि आप जिस वस्तु को शब्दकोश से हटा रहे हैं उसे अन्य चर द्वारा संदर्भित किया गया है तो यह अभी भी पहुंच योग्य है, इस प्रकार यह कचरा नहीं है, इसलिए इसे हटाया नहीं जाएगा। यदि आप सामान्य रूप से कचरे के संग्रह और विशेष रूप से अजगर के कचरे के संग्रह के बारे में पढ़ने में रुचि रखते हैं, तो मैं आपको कुछ लिंक छोड़ देता हूं।

3

यह del d['foo'] पर कॉल करने जैसा ही है - यह केवल प्रविष्टियों को हटा देता है, लेकिन यह कुंजी या मूल्यों को स्वयं प्रभावित नहीं करता है।

बेशक, यदि वे कोई अन्य संदर्भ नहीं हैं तो वे कचरा इकट्ठा हो सकते हैं।

+2

दूसरे शब्दों में, यदि कुंजी या मान साझा किए जाते हैं (किसी अन्य चर को सौंपा गया), तो उनकी ऑब्जेक्ट्स को हटाया नहीं जाएगा और न ही 'd.clear()', और न ही 'del d [ कुंजी] '। एक कुंजीपटल स्टोर दोनों कुंजी और मूल्यों के संदर्भ। ऑपरेशन द्वारा * संदर्भ हटा दिए जाते हैं। – pepr

+0

@pepr यह सही है। – Marcin

+0

हाँ, इसलिए जिस कुंजी को मैं याद कर रहा था वह है डिलीट ऑपरेशन केवल संदर्भ को हटा देता है, मेमोरी क्लीयरेंस कचरा कलेक्टर – 0xc0de

1

आपके मामले में, दो MyClass वस्तुओं को साझा किया जाता है। वे अभी भी my_obj_1 और my_obj_2 के माध्यम से पहुंच योग्य होंगे।

5

यह dict के माध्यम से पाशन और del उन्हें eting से अलग तरीके से व्यवहार करता है?

यह यहाँ है कि किसी भी कस्टम MutableMapping सार आधार वर्ग को लागू करने वर्ग clear() एक "मुक्त" mixin पद्धति के रूप में हो जाता है ध्यान देने योग्य है।

केवल तरीकों आप एक MutableMapping उपवर्ग का दृष्टांत में ओवरराइड करने के लिए की जरूरत है:

__getitem__, __setitem__, __delitem__, __iter__, __len__ 

के बाद से आप अपनी पसंद के किसी भी तरह से अपने मानचित्रण कक्षा में डेटा स्टोर कर सकते हैं, एक ही रास्ता clear() यह पता लगाने कैसे कर सकते हैं वास्तव में अपने डेटा को साफ़ करने के लिए उन पांच तरीकों में से एक या अधिक का उपयोग कर है। अब, आपको लगता है कि clear() किस तरीके का उपयोग कर रहा है, लेकिन अनुमान लगाया जा सकता है कि हम प्रयोग कर सकते हैं?

import collections 

class MyMap(collections.MutableMapping): 
    def __init__(self, mydict): 
     self._top_secret_data = mydict 

    def __getitem__(self, key): 
     print 'getitem' 
     return self._top_secret_data[key] 

    def __setitem__(self, key, value): 
     raise Exception('where did you want that?') 

    def __len__(self): 
     raise Exception('a gentleman never tells') 

    def __delitem__(self, key): 
     print '[shredding intensifies]' 
     del self._top_secret_data[key] 

    def __iter__(self): 
     def keygen(): 
      for key in self._top_secret_data: 
       print 'faster! faster!' 
       yield key 
     return iter(keygen()) 

वर्ग ऊपर परिभाषित का उपयोग करना, यह देखने के लिए clear() कैसे कार्यान्वित किया जाता है आसान है:

>>> m = MyMap({1:'a', 2:'b', 3:'c'}) 
>>> m.clear() 
faster! faster! 
getitem 
[shredding intensifies] 
faster! faster! 
getitem 
[shredding intensifies] 
faster! faster! 
getitem 
[shredding intensifies] 
>>> 

दूसरे शब्दों में, clear() mixin विधि मूल रूप से for key in self: del self[key] के रूप में कार्यान्वित किया जाता है।

अब, एक अस्वीकरण: dict जैसे अंतर्निहित प्रकार सी में लागू किए गए हैं, इसलिए dict.clear विधि सचमुच for key in mydict: del mydict[key] के समान नहीं हो सकती है। मैं दृश्यों के पीछे कुछ अनुकूलन की अपेक्षा करता हूं, शायद एक पूरी तरह से अलग रणनीति - लेकिन उम्मीद है कि यह उदाहरण आपको clear() पायथन में काम करने की विधि के बारे में कुछ विचार देता है।

4

वास्तव में दोनों के बीच बहुत छोटा अंतर है। clear() कुंजी को हटाते समय, हैशसेट में उपयोग की गई हैशसेट की स्मृति को मुक्त कर देगा।

a = dict.fromkeys(range(1000)) 

In [10]: sys.getsizeof(a) 
Out[10]: 49432 

In [11]: a.clear() 

In [12]: sys.getsizeof(a) 
Out[12]: 280 

In [13]: a = dict.fromkeys(range(1000)) 

In [14]: for i in range(1000): 
    ....:  del a[i] 
    ....:  

In [15]: sys.getsizeof(a) 
Out[15]: 49432 
+0

द्वारा संभाला जाता है! मुझे वही चीज़ मिली, और यह बहुत महत्वपूर्ण है, जब आप वास्तव में बड़े नियम से निपटते हैं। मैं सभी चाबियों को हटाने के लिए कभी भी 'लूप' का उपयोग नहीं करता, क्योंकि यह स्मृति को वापस नहीं छोड़ता है और इसलिए इसका कोई मतलब नहीं है –

1

डेल आदेश सूची में विशेष आइटम के संदर्भ हटाने के लिए, स्पष्ट आदेश स्पष्ट सभी प्रमुख मूल्य एक में जोड़े तो जाना कार्यक्षमता ही वे दोनों भिन्नता और स्मृति से इसे हटाने के बाकी काम है है कचरा कलेक्टर द्वारा किया गया

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