我真的想不出Python需要del关键字的任何原因(而且大多数语言似乎都没有类似的关键字)。例如,与其删除变量,还不如将None赋值给它。当从字典中删除时,可以添加del方法。

在Python中保留del是有原因的吗,还是它是Python前垃圾收集时代的遗迹?


当前回答

还有一个小众用途: 在带有ROOT5或ROOT6的pyroot中,"del"可以用于删除引用不再存在的c++对象的python对象。这允许pyroot的动态查找找到同名的c++对象,并将其绑定到python名称。所以你可以有这样一个场景:

import ROOT as R
input_file = R.TFile('inputs/___my_file_name___.root')
tree = input_file.Get('r')
tree.Draw('hy>>hh(10,0,5)')
R.gPad.Close()
R.hy # shows that hy is still available. It can even be redrawn at this stage.
tree.Draw('hy>>hh(3,0,3)') # overwrites the C++ object in ROOT's namespace
R.hy # shows that R.hy is None, since the C++ object it pointed to is gone
del R.hy
R.hy # now finds the new C++ object

希望ROOT7的更健全的对象管理能够填补这个空缺。

其他回答

删除变量与将其设置为None不同

使用del删除变量名可能很少使用,但如果没有关键字,这是无法实现的。如果你可以通过写a=1来创建一个变量名,那么理论上你可以通过删除a来撤销这一点。

在某些情况下,它可以使调试更容易,因为试图访问已删除的变量将引发NameError。

可以删除类实例属性

Python允许你编写如下代码:

class A(object):
    def set_a(self, a):
        self.a=a
a=A()
a.set_a(3)
if hasattr(a, "a"):
    print("Hallo")

如果选择向类实例动态添加属性,当然希望能够通过写入来撤销它

del a.a

还有一个小众用途: 在带有ROOT5或ROOT6的pyroot中,"del"可以用于删除引用不再存在的c++对象的python对象。这允许pyroot的动态查找找到同名的c++对象,并将其绑定到python名称。所以你可以有这样一个场景:

import ROOT as R
input_file = R.TFile('inputs/___my_file_name___.root')
tree = input_file.Get('r')
tree.Draw('hy>>hh(10,0,5)')
R.gPad.Close()
R.hy # shows that hy is still available. It can even be redrawn at this stage.
tree.Draw('hy>>hh(3,0,3)') # overwrites the C++ object in ROOT's namespace
R.hy # shows that R.hy is None, since the C++ object it pointed to is gone
del R.hy
R.hy # now finds the new C++ object

希望ROOT7的更健全的对象管理能够填补这个空缺。

只是另一种想法。

当在Django这样的框架中调试http应用程序时,调用堆栈中充满了以前使用过的无用和混乱的变量,特别是当它是一个非常长的列表时,这对开发人员来说是非常痛苦的。因此,在这一点上,名称空间控制可能是有用的。

我发现在使用Numpy处理大数据时,del对于伪手动内存管理非常有用。例如:

for image_name in large_image_set:
    large_image = io.imread(image_name)
    height, width, depth = large_image.shape
    large_mask = np.all(large_image == <some_condition>)
    # Clear memory, make space
    del large_image; gc.collect()

    large_processed_image = np.zeros((height, width, depth))
    large_processed_image[large_mask] = (new_value)
    io.imsave("processed_image.png", large_processed_image)

    # Clear memory, make space
    del large_mask, large_processed_image; gc.collect()

当Python GC无法跟上时,系统会疯狂地切换,这可能会导致脚本停止,而它在宽松的内存阈值下运行得非常流畅,从而在机器工作时留下了足够的空间来使用机器浏览和编码。

首先,你可以删除除局部变量之外的其他东西

del list_item[4]
del dictionary["alpha"]

这两者显然都是有用的。其次,在局部变量上使用del使意图更加明确。比较:

del foo

to

foo = None

我知道在del foo的情况下,目的是从作用域中删除变量。foo = None是否这样做还不清楚。如果有人只是赋值foo = None,我可能会认为这是死代码。但我立刻就知道,编码del foo的人想要做什么。