在Python中对局部变量使用显式del

17 投票
4 回答
18713 浏览
提问于 2025-04-15 18:50

在Python中,使用明确的del语句有什么最佳实践和建议?我知道它是用来删除属性或者字典/列表中的元素等等,但有时候我看到它在代码中用来删除局部变量,像这样:

def action(x):
    result = None
    something = produce_something(x)
    if something:
        qux = foo(something)
        result = bar(qux, something)
        del qux
    del something
    return result

这样写代码有什么严重的理由吗?

补充说明:假设quxsomething是一些“简单”的东西,没有__del__方法。

4 个回答

3

当你在运行处理大量数据的程序时(根据我的经验,当程序的总内存使用量接近1GB时),删除一些对象,比如:

del largeObject1

del largeObject2

……

这样做可以给你的程序腾出必要的空间,让它在不耗尽内存的情况下正常运行。这可能是修改程序的最简单方法,尤其是在遇到“内存错误”(MemoryError)这种运行时错误时。

4

不。

我相信会有人提出一些奇怪的理由来这样做,比如为了确保在变量不再有效后,别人不会不小心使用它。但很可能写这段代码的人只是搞混了。你可以把它们删掉。

38

我不记得上次使用过 del 是什么时候了——其实用到它的机会非常少,通常只是用来在需要的 import 之后清理一下模块的命名空间。

特别要注意的是,之前有个(现在已经删除的)回答说:

使用 del 是确保一个对象的 __del__ 方法被调用的唯一方法。

这其实是错误的,理解这一点非常重要。为了帮助大家理解,我们来创建一个带有 __del__ 方法的类,看看它什么时候被调用:

>>> class visdel(object):
...   def __del__(self): print 'del', id(self)
... 
>>> d = visdel()
>>> a = list()
>>> a.append(d)
>>> del d
>>>

看到了吗? del 并不能“确保” __del__ 被调用:del 只是移除一个引用,只有当最后一个引用被移除时,__del__ 才会被调用。所以,还有:

>>> a.append(visdel())
>>> a[:]=[1, 2, 3]
del 550864
del 551184

当最后一个引用消失时(这包括一些不涉及 del 的情况,比如像这个例子中的切片赋值,或者其他名称和槽的重新绑定),这时 __del__ 就会被调用——无论 del 是否参与了减少对象的引用,这一点完全没有影响。

所以,除非你有特别的理由需要清理命名空间(通常是模块的命名空间,但也可能是类或实例的命名空间),否则就别费心去用 del 了(偶尔用来从容器中移除一个项目还算方便,但我发现我通常会用容器的 pop 方法或者直接赋值来处理这些情况,甚至连这个都不太用!)。

撰写回答