“弱引用对象不再存在”是啥意思?
Posted
技术标签:
【中文标题】“弱引用对象不再存在”是啥意思?【英文标题】:What does it mean "weakly-referenced object no longer exists"?“弱引用对象不再存在”是什么意思? 【发布时间】:2010-12-01 17:08:47 【问题描述】:我正在运行 Python 代码并收到以下错误消息:
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')
【问题讨论】:
【参考方案1】:一个普通的 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 不会介意(您只会让读者感到困惑)。
【讨论】:
【参考方案2】:代码引用了一个已经被垃圾回收的实例。 为避免循环引用,您可以使用不足以防止垃圾收集的弱引用。在这种情况下,searchengine.crawler 对象有一个weakref.proxy (http://docs.python.org/library/weakref.html#weakref.proxy)。
【讨论】:
循环引用真的能阻止python中的GC吗?! 我读到__del__()
用 Python 编写时会在循环引用的情况下阻止 GC。
Bastien 是对的:python.org/doc/3.0/reference/datamodel.html#object.__del__ 其中指出:>【参考方案3】:
弱引用是一种引用形式,它不会阻止垃圾收集器处理被引用的对象。如果要保证对象将继续存在,则应使用强(正常)引用。
否则,在所有正常引用都超出范围后,无法保证该对象是否存在。
【讨论】:
问题是我不知道“弱”或“强”引用是什么意思。我什至不知道参考是什么意思。以上是关于“弱引用对象不再存在”是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章