2012-02-17 16 views
7

मैं एक साधारण मंच गेम लिख रहा हूं, और मुझे पता चला है कि 'भूत' उदाहरणों को हटाते समय, वे बने रहते हैं और कचरे को एकत्र नहीं करते हैं। ऐसा लगता है कि हालांकि मैं सभी संदर्भों को हटा रहा हूं, भूत वस्तुओं में कुछ प्रकार के आंतरिक संदर्भ हैं जो उन्हें कचरा इकट्ठा करने से रोक रहे हैं। विशेष रूप से उनके पास गुण होते हैं जो विधि स्विच होते हैं।आंतरिक संदर्भ कचरा संग्रह

import weakref 

weak_ghosts = weakref.WeakKeyDictionary() 

class Ghost(object): 
    def __init__(self): 
     #pass 
     self.switch = {'eat':self.eat, 'sleep':self.sleep} 

    def eat(self): 
     pass 

    def sleep(self): 
     pass 

ghost = Ghost() 
weak_ghosts[ghost] = None 
#ghost.switch = {} # uncomment this line and ghost is successfully removed 
del ghost 
print "number of ghosts =", len(weak_ghosts) 

#output: 
number of ghosts = 1 

सवाल::

  1. क्या वास्तव में हो रहा है

    निम्नलिखित कोड मेरी समस्या को दिखाता है?

  2. इस स्थिति से बचने के लिए मुझे क्या करना चाहिए?
  3. क्या मैं विधियों के एक स्विच करने योग्य शब्दकोश बनाने के लिए सही पद्धति का उपयोग कर रहा हूं?

उत्तर

4

self.switch द्वारा निर्मित एक गोलाकार संदर्भ है जिसका उद्देश्य उस भाग का संदर्भ देता है। इस की जाँच करें:

import weakref 

class Ghost(object): 
    def __init__(self): 
     #pass 
     self.switch = {'eat':self.eat, 'sleep':self.sleep} 

    def eat(self): 
     pass 

    def sleep(self): 
     pass 

ghost = Ghost() 

def callback(o): 
    print 'callback', o 

wref = weakref.ref(ghost, callback) 
print 'del ghost' 
del ghost 
print 'after del ghost' 

प्रिंटों:

del ghost 
after del ghost 
callback <weakref at 00B55FC0; dead> 

तो वास्तविक वस्तु सिर्फ शटडाउन होने पर साफ किया गया था।

आप प्रभाव देखने के लिए मैन्युअल रूप से जीसी चला सकते हैं। ऊपर स्क्रिप्ट के अंत करने के लिए इस जोड़ें:

print 'gc.collect' 
import gc 
gc.collect() 
print 'after gc.collect' 

अब आप देखेंगे:

del ghost 
after del ghost 
gc.collect 
callback <weakref at 00B55FC0; dead> 
after gc.collect 

ध्यान दें कि डिफ़ॉल्ट रूप से, इस जीसी सक्षम है और समय-समय पर चलेंगे। यह आपके ghost ऑब्जेक्ट्स को साफ़ कर देगा क्योंकि वे पहुंचने योग्य परिपत्र संदर्भ बन जाते हैं।

class Ghost(object): 
    def __init__(self): 
     self.switch = {'eat':Ghost.eat, 'sleep':Ghost.sleep} 

तो तरीकों अनबाउंड रखा जाता है:

2

एक विकल्प करना है।

+1

लेकिन फिर वास्तव में उन्हें कॉल करते समय ऑब्जेक्ट को स्पष्ट रूप से पास करना याद रखें –

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