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

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


当前回答

我想详细说明公认的答案,以强调将变量设置为None与使用del删除变量之间的细微差别:

给定变量foo = 'bar',函数定义如下:

def test_var(var):
    if var:
        print('variable tested true')
    else:
        print('variable tested false')

一旦初始声明,test_var(foo)产生的变量测试为true。

现在试一试:

foo = None
test_var(foo)

它产生的变量测试为假。

将这种行为与以下行为进行对比:

del foo
test_var(foo)

现在会引发NameError: name 'foo'没有定义。

其他回答

当你使用sys.exc_info()检查异常时,有一个特定的例子说明你应该使用del(可能还有其他的例子,但我知道这个是现成的)。这个函数返回一个元组、引发的异常类型、消息和一个回溯。

前两个值通常足以诊断错误并对其进行处理,但第三个值包含从引发异常的位置到捕获异常的位置之间的整个调用堆栈。特别是,如果你做

try:
    do_evil()
except:
    exc_type, exc_value, tb = sys.exc_info()
    if something(exc_value):
        raise

回溯,TB最终在调用堆栈的局部变量中,创建了一个不能被垃圾收集的循环引用。因此,重要的是要做到:

try:
    do_evil()
except:
    exc_type, exc_value, tb = sys.exc_info()
    del tb
    if something(exc_value):
        raise

打破循环引用。在许多情况下,您希望调用sys.exc_info(),就像使用元类魔法一样,回溯是有用的,因此您必须确保在可能离开异常处理程序之前清除它。如果你不需要回溯,你应该立即删除它,或者直接执行:

exc_type, exc_value = sys.exc_info()[:2]

一起避免这一切。

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

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

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

del foo

to

foo = None

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

Del删除变量及其所指向的对象的绑定。

>>> a = ['a', 'b', 'c']
>>> b = a
>>> del a
>>> b
['a', 'b', 'c']
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined

我能想到的一个简单的用例是,如果你已经使用内置函数名作为变量,并且你想在它已经被你的变量名“覆盖”之后使用该函数。

t = ('a', "letter")
value, type = t
print(value, type)
del type
print(type(value))

输出:

a letter
<class 'str'>

I think one of the reasons that del has its own syntax is that replacing it with a function might be hard in certain cases given it operates on the binding or variable and not the value it references. Thus if a function version of del were to be created a context would need to be passed in. del foo would need to become globals().remove('foo') or locals().remove('foo') which gets messy and less readable. Still I say getting rid of del would be good given its seemingly rare use. But removing language features/flaws can be painful. Maybe python 4 will remove it :)

由于我还没有看到交互式控制台的答案,我将展示一个。

当foo=None时,该引用和对象存在,它不指向它。

而del foo也会销毁对象和引用。

如果你这样做如果foo是None并且它被删除了它就会升起NameError作为引用,它的对象所有介于两者之间的东西都会被del删除

删除目标列表会递归地从左到右删除每个目标。

与此同时,foo=None只是一个指向None的引用,因此引用仍然是有效的,对象也是如此。

[…在Python中,变量是对象的引用,任何变量都可以引用任何对象[…]

链接到引用1

链接到引用2