Python中类的del用法
假设我们在Python中有一个类:
class A(object):
def __del__(self):
print "Del!"
当删除或进行垃圾回收时,任何类的实例都会调用__del__
这个方法。
那么,能否为整个类做同样的事情呢?我希望在类本身被垃圾回收时,有一个方法被调用,我猜这个是在脚本结束的时候发生的。
提前感谢任何指点!
编辑:正如我预期的那样,大家都在劝我不要使用这种技术(我自己可能也会这么评论 :)),不过问题依然存在:这可能吗?
我想要的是:我有一个类里面有一个静态成员需要被清理。
class A(object):
class Meta(type):
def __new__(mcs, name, bases, attrs):
attrs['conn'] = sqlite3.connect( DB_FILE )
return type.__new__(mcs, name, bases, attrs)
__metaclass__ = Meta
我希望在程序关闭之前调用A.conn.close()
,也就是说,在我知道不会再创建任何的实例的时候。我知道可以用atexit
来做到这一点,但这看起来实在是太丑陋了。
1 个回答
7
这个问题是因为类里面有循环引用,也就是说它们会互相指向自己。所以当这些类被删除的时候,它们不容易被清理掉,因此元类的 __del__
方法不会被调用。
我可以在 Pypy 的 Python 实现中触发这个方法被调用,但在 cpython 中,无论是 2.6 还是 3.2 都不行。即使要触发它,我还得手动调用垃圾回收器——在程序退出时,Python 环境通常会出现很多不一致的情况,因此 __del__
方法在内部信息足够的情况下被调用的机会非常小。
下面是我在 Pypy 中触发类的 __del__
方法的会话记录:
~]$ pypy
Python 2.5.2 (78826, Nov 29 2010, 00:18:05)
[PyPy 1.4.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
And now for something completely different: ``sorry, I'll teach the cactus how
to swim later''
>>>> import gc
>>>> class Meta(type):
.... def __del__(cls):
.... print ("Arghh!!")
....
>>>> class A(object):
.... __metaclass__ = Meta
....
>>>> del A
>>>> gc.collect()
Arghh!!
0
>>>>
2022 - 从 Python 3.11 a06 开始,如果在删除所有指向类的引用后调用 gc.collect()
,那么在 cPython 中元类的 __del__
方法就能正常工作,就像在这个例子中 Pypy 的表现一样。