“弱引用对象不再存在”是啥意思?

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】:

弱引用是一种引用形式,它不会阻止垃圾收集器处理被引用的对象。如果要保证对象将继续存在,则应使用强(正常)引用。

否则,在所有正常引用都超出范围后,无法保证该对象是否存在。

【讨论】:

问题是我不知道“弱”或“强”引用是什么意思。我什至不知道参考是什么意思。

以上是关于“弱引用对象不再存在”是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

Kivy Apk Buildozer:ReferenceError:弱引用对象不再存在

linux 中加号是啥意思

ES6 WeakMap 的实际用途是啥?

类引用前的 * 是啥意思?

术语“取消引用”对象到底是啥意思?

JavaScript 对象的“值是引用”是啥意思