当前位置:  开发笔记 > 编程语言 > 正文

从列表中调用元素的析构函数

如何解决《从列表中调用元素的析构函数》经验,为你挑选了1个好方法。

我有类似的东西:

a = [instance1, instance2, ...]

如果我做了

del a[1]

instance2从列表中删除,但是实例2的析构函数方法是否被调用?

我对此感兴趣,因为我的代码使用了大量内存,我需要释放内存从列表中删除实例.



1> Rick support..:

来自像c ++这样的语言(正如我所做的那样),这往往是许多人在第一次学习Python时难以掌握的主题.

底线是这样的:当你这样做时del XXX,你永远不会*在你使用时删除一个对象del.您只是删除对象引用.但是,在实践中,假设没有其他参考instance2对象放置,从列表中删除它将根据需要释放内存.

如果您不理解对象和对象引用之间的区别,请继续阅读.

Python:按值传递,或通过引用传递?

您可能熟悉通过引用或值将参数传递给函数的概念.但是,Python以不同的方式做事.参数始终通过对象引用传递.阅读本文以获得有用的解释.

总结一下:这意味着当你将一个变量传递给一个函数时,你没有传递变量值的副本(按值传递),也没有传递对象本身 - 即内存中值的地址.您正在传递间接引用内存中保存的值的名称对象.

这与del... 有什么关系?

好吧,我会告诉你的.

说你这样做:

def deleteit(thing):
    del thing

mylist = [1,2,3]
deleteit(mylist)

......你认为会发生什么?已经mylist被从全局名字空间中删除?

答案是不:

assert mylist # No error

原因是当您del thingdeleteit函数中执行时,您只是删除对该对象的本地对象引用.该对象引用仅存在于函数内部.作为侧边栏,您可能会问:是否可以在函数内部从全局命名空间中删除对象引用?答案是肯定的,但您必须首先将对象引用声明为全局命名空间的一部分:

def deletemylist():
    global mylist
    del mylist

mylist = [1,2,3]
deletemylist()
assert mylist #ERROR, as expected
把它们放在一起

现在回到原来的问题.在任何名称空间中,当您执行此操作时:

del XXX

...您没有删除XXX表示的对象.你不能这样做.您只删除了对象引用 XXX,它引用了内存中的某个对象.对象本身由Python内存管理器管理.这是一个非常重要的区别.

请注意,因此,当您覆盖__del__某个对象的方法时,该对象在删除对象时被调用(而不是对象引用!):

class MyClass():
    def __del__(self):
        print(self, "deleted")
        super().__del__()

m = MyClass()
del m

... __del__方法中的print语句不一定会在您执行后立即发生del m.它只发生在删除对象本身的时间点,这不取决于你.这取决于Python内存管理器.删除所有名称空间中的所有对象引用后,__del__最终将执行该方法.但不一定立即.

删除作为列表一部分的对象引用时也是如此,就像在原始示例中一样.当你这样做时del a[1],只a[1]删除对所指示的对象的对象引用,并且__del__可以立即调用或不调用该对象的方法(尽管如前所述,一旦没有对该对象的引用,它将最终被调用,并且该对象由内存管理器进行垃圾回收).

因此,不建议您将__del__方法放在想要立即执行的方法中del mything,因为它可能不会发生这种情况.


*我相信它永远不会.不可避免地有人可能会回复我的回答,并发表评论,讨论该规则的例外情况.但是whatevs.

推荐阅读
mobiledu2402851323
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有