python - 引用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 次,但是为什么。感谢帮助
解决方案
首先是一些基本事实。
- CPython 使用引用计数。当对象的引用计数降至 0 时,对象将被取消分配。
并非所有对象都由
gc
模块处理。从文档中:作为一般规则,不跟踪原子类型的实例,而跟踪非原子类型(容器、用户定义的对象……)的实例。
Python“变量”实际上是引用对象的名称。
因此,当您这样做时c = o
,您会创建对引用的同一类O
实例的第二个o
引用。这就是为什么它们具有相同的id
.
根据定义,当一个对象被释放时,不再有对它的引用。因此,您无法再获得对它的引用。
编辑:
你的印象__del__
似乎有点颠倒。它通常会在引用计数达到 0 后由 Python 调用,请参阅相关文档。但是如果你的程序调用了一个对象的__del__
方法,那并不会神奇地删除所有的引用!有关更详细的说明,请参阅此答案(以及前面提到的文档)。
双下划线方法(或“dunder”方法)供 Python 在内部使用以提供某些功能。通常,您不应该从您的程序中调用它们。
推荐阅读
- typescript - Typescript 在 MacOS 上被错误识别为 MPEG 文件
- laravel - Laravel 返回带条件的关系数据
- javascript - 如何获得平均星级值(原生 mongodb & express)
- sql - 算术溢出错误将 nvarchar 转换为数据类型 numeric 以防万一查询
- java - 为什么反转一个 ArrayList 变量也会反转另一个?
- sql - SQL-在 1 列中获取具有多个值的值
- c - 如何直接打印最后一个错误代码,C中的文本
- python - 如何从 selenium 中的元素中删除属性
- javascript - 每次单击不同的按钮时,Textarea 中的文本都会发生变化
- gtsummary - 模型中的 tbl_regression 样本大小 - gtsummary