首页 > 解决方案 > 引用python中已删除的对象

问题描述

__del__首先,我知道当它的函数被gc隐式调用或显式调用时,对象被破坏(或销毁) 。好的,为什么我可以在这个对象被销毁后通过它的引用来获取对象的成员变量。

python版本是3.7.1

class O():
    def __init__(self):
        self.name = 'I am a O'
    def __del__(self):
        print('Oops, O is deleted')

if __name__ == '__main__':
    o = O()
    c = o
    print(id(o))
    o.__del__()
    print(c.name)
    print(id(c))

结果

2473601495560
Oops, O is deleted
I am a O
2473601495560
Oops, O is deleted

我们可以发现问题存在,并且 destruct 函数被调用了 2 次,但是为什么。感谢帮助

标签: pythonreference

解决方案


首先是一些基本事实。

  • CPython 使用引用计数。当对象的引用计数降至 0 时,对象将被取消分配。
  • 并非所有对象都由gc模块处理。从文档中:

    作为一般规则,不跟踪原子类型的实例,而跟踪非原子类型(容器、用户定义的对象……)的实例。

  • Python“变量”实际上是引用对象的名称。

因此,当您这样做时c = o,您会创建对引用的同一类O实例的第二个o引用。这就是为什么它们具有相同的id.

根据定义,当一个对象被释放时,不再有对它的引用。因此,您无法再获得对它的引用。

编辑: 你的印象__del__似乎有点颠倒。它通常会在引用计数达到 0 后由 Python 调用,请参阅相关文档。但是如果你的程序调用了一个对象的__del__方法,那并不会神奇地删除所有的引用!有关更详细的说明,请参阅此答案(以及前面提到的文档)。

双下划线方法(或“dunder”方法)供 Python 在内部使用以提供某些功能。通常,您不应该从您的程序中调用它们。


推荐阅读