什么意思“弱引用对象不再存在”?

时间:2009-09-26 20:42:09

标签: python

我正在运行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')

3 个答案:

答案 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)。