2009-09-26 12 views
10

मैं एक अजगर कोड चल रहा हूँ और मैं निम्न त्रुटि संदेश मिलता है:इसका क्या अर्थ है "कमजोर-संदर्भित वस्तु अब मौजूद नहीं है"?

Exception exceptions.ReferenceError: 'weakly-referenced object no longer exists' in <bound method crawler.__del__ of <searchengine.crawler instance at 0x2b8c1f99ef80>> ignored 

किसी को भी पता है क्या कर सकते हैं इसका मतलब है?

पीएस इस कोड को जो त्रुटि उत्पन्न है:

import sqlite 

class crawler: 

    def __init__(self,dbname): 
    tmp = sqlite.connect(dbname) 
    self.con = tmp.cursor() 

    def __del__(self): 
    self.con.close() 

crawler = crawler('searchindex.db') 

उत्तर

19

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

जब आप किसी ऑब्जेक्ट को जीवित रहने की इच्छा नहीं रखते हैं, क्योंकि कोई अन्य इसे संदर्भित करता है, तो आप एक "कमजोर संदर्भ" का उपयोग करते हैं, संदर्भ की एक विशेष विविधता जो आरसी में वृद्धि नहीं करती है; विवरण के लिए the docs देखें। बेशक, चूंकि संदर्भित वस्तु को दूर किया जा सकता है यदि अन्यथा संदर्भित नहीं किया जाता है (सामान्य सामान्य की बजाय कमजोर रेफरी का पूरा उद्देश्य!), तो ऑब्जेक्ट का उपयोग करने का प्रयास करने पर ऑब्जेक्ट को संदर्भित करने की आवश्यकता है यह दूर चला गया है - और उस अलर्ट को आप जो अपवाद देख रहे हैं उसे बिल्कुल दिया गया है।

अपने कोड में ...:

def __init__(self,dbname): 
    tmp = sqlite.connect(dbname) 
    self.con = tmp.cursor() 

    def __del__(self): 
    self.con.close() 

tmp कनेक्शन के लिए एक सामान्य संदर्भ है ... लेकिन यह एक स्थानीय चर है, इसलिए इसे __init__ के अंत में चला जाता है। (विशेष रूप से नामित ;-) कर्सर self.con रहता है, लेकिन यह आंतरिक रूप से कनेक्शन के लिए एक WEAK रेफरी रखने के लिए आंतरिक रूप से कार्यान्वित किया जाता है, इसलिए tmp करता है जब कनेक्शन दूर हो जाता है। तो __del__ में .close पर कॉल विफल हो जाता है (क्योंकि कर्सर को स्वयं को बंद करने के लिए कनेक्शन का उपयोग करने की आवश्यकता है)।

सरल समाधान निम्नलिखित छोटे परिवर्तन है:

def __init__(self,dbname): 
    self.con = sqlite.connect(dbname) 
    self.cur = self.con.cursor() 

    def __del__(self): 
    self.cur.close() 
    self.con.close() 

मैं भी कनेक्शन और कर्सर के लिए CUR के लिए चोर उपयोग करने का अवसर ले लिया है, लेकिन अजगर कोई आपत्ति नहीं होगा अगर आप उन स्वैप करने के लिए उत्सुक हैं (आप केवल पाठकों को परेशान छोड़ देंगे ;-)।

1

कमजोर संदर्भ संदर्भ का एक रूप है कि संदर्भित वस्तु निपटान से कचरा कलेक्टर नहीं रोकता है। यदि आप गारंटी देना चाहते हैं कि ऑब्जेक्ट मौजूद रहेगा, तो आपको एक मजबूत (सामान्य) संदर्भ का उपयोग करना चाहिए।

अन्यथा, इस बात की कोई गारंटी नहीं है कि ऑब्जेक्ट सभी सामान्य संदर्भों के दायरे से बाहर हो जाने के बाद मौजूद होगा या नहीं होगा।

+3

समस्या यह है कि मुझे नहीं पता कि "कमजोर" या "मजबूत" संदर्भ का अर्थ क्या है। मैं यह भी नहीं जानता कि संदर्भ का क्या अर्थ है। – Verrtex

1

कोड एक उदाहरण का जिक्र कर रहा है जो पहले से ही कचरा एकत्रित किया गया है। परिपत्र संदर्भों से बचने के लिए आप एक कमजोर संदर्भ का उपयोग कर सकते हैं जो कचरा संग्रह को रोकने के लिए पर्याप्त नहीं है। इस मामले में एक searchengine.crawler ऑब्जेक्ट में एक weakref.proxy (http://docs.python.org/library/weakref.html#weakref.proxy) है।

+0

सर्कुलर संदर्भ वास्तव में जीसी को पायथन में रोकते हैं ?! – recursive

+0

मैंने पढ़ा है कि '__del __()' पाइथन में लिखे गए परिपत्र संदर्भों के मामले में जीसी को रोकता है। –

+1

बैस्टियन सही है: http://www.python.org/doc/3.0/reference/datamodel.html#object।__del__ जो कहता है: << विकल्प चक्र डिटेक्टर सक्षम होने पर सर्कुलर संदर्भ जो कचरा होते हैं (यह डिफ़ॉल्ट रूप से चालू होता है), लेकिन केवल पाइथन-स्तर __del __() विधियों में शामिल होने पर ही साफ़ किया जा सकता है। साइकिल डिटेक्टर द्वारा विशेष रूप से कचरे के मूल्य का वर्णन कैसे किया जाता है, इस बारे में अधिक जानकारी के लिए जीसी मॉड्यूल के लिए दस्तावेज का संदर्भ लें कि __del __() विधियों को कैसे नियंत्रित किया जाता है। >> – Francesco

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