我正在运行Python代码,并收到以下错误消息:
Exception exceptions.ReferenceError: 'weakly-referenced object no longer exists' in <bound method crawler.__del__ of <searchengine.crawler instance at 0x2b8c1f99ef80>> ignored
有人知道这意味着什么吗?
P.S。 这是产生错误的代码:
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')
答案 0 :(得分:29)
正常的AKA强引用是使引用对象保持活动的引用:在CPython中,每个对象保留存在的(正常)引用数(称为“引用计数”或RC)并消失一旦RC达到零(偶尔的世代标记和扫描通道也会偶尔垃圾收集“参考循环”)。
如果你不希望某个对象只是因为另一个引用它而保持活着,那么你使用一个“弱引用”,一种不增加RC的特殊参考。有关详细信息,请参阅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()
我也借此机会使用con连接和cur用于光标,但是如果你热衷于交换它们,Python会不介意(你只会让读者感到困惑; - )。
答案 1 :(得分:1)
弱引用是一种引用形式,它不会阻止垃圾收集器处理引用的对象。如果要保证对象将继续存在,则应使用强(正常)引用。
否则,在所有正常引用超出范围后,无法保证对象将存在或不存在。
答案 2 :(得分:1)
代码指的是已经被垃圾收集的实例。 要避免循环引用,可以使用弱引用,这不足以防止垃圾回收。在这种情况下,serefineine.crawler对象有一个weakref.proxy(http://docs.python.org/library/weakref.html#weakref.proxy)。