python中对已删除对象的引用

2024-04-26 13:07:24 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

我们可以发现问题存在,并且析构函数被调用了两次,但是为什么。谢谢你的帮助


Tags: 对象函数nameselfidisdefam
1条回答
网友
1楼 · 发布于 2024-04-26 13:07:24

首先是一些基本事实。你知道吗

  • CPython使用参考计数。当对象的引用计数降至0时,将取消分配对象。你知道吗
  • 并非所有对象都由gc模块处理。根据文件:

    As a general rule, instances of atomic types aren’t tracked and instances of non-atomic types (containers, user-defined objects…) are.

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

因此,在执行c = o操作时,将创建对o引用的同一类O实例的第二个引用。这就是为什么它们有相同的id。你知道吗

根据定义当对象被取消分配时,不再有对它的引用。所以你再也找不到它的参考了。你知道吗

编辑: 你对__del__的印象有点颠倒。它通常在引用计数达到0之后由Python调用,请参见relevant documentation。 但是如果你的程序调用一个对象的__del__方法,那就不会神奇地删除所有引用!请参阅this answer(以及前面提到的文档)以获得更详细的解释。你知道吗

双下划线方法(或“dunder”方法)供Python在内部使用,以提供一些功能。你通常不应该从你的程序中给他们打电话。你知道吗

相关问题 更多 >