在Python中对局部变量使用显式del
在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
这样写代码有什么严重的理由吗?
补充说明:假设qux
和something
是一些“简单”的东西,没有__del__
方法。
4 个回答
当你在运行处理大量数据的程序时(根据我的经验,当程序的总内存使用量接近1GB时),删除一些对象,比如:
del largeObject1
del largeObject2
……
这样做可以给你的程序腾出必要的空间,让它在不耗尽内存的情况下正常运行。这可能是修改程序的最简单方法,尤其是在遇到“内存错误”(MemoryError)这种运行时错误时。
不。
我相信会有人提出一些奇怪的理由来这样做,比如为了确保在变量不再有效后,别人不会不小心使用它。但很可能写这段代码的人只是搞混了。你可以把它们删掉。
我不记得上次使用过 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
方法或者直接赋值来处理这些情况,甚至连这个都不太用!)。