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

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


当前回答

除非重新初始化,否则Del将从当前作用域删除变量。将其设置为None将其保留在当前范围内。

a = "python string"        
print(a)
del a
print(a)
a = "new python string"
print(a)

输出:

python string
Traceback (most recent call last):
  File "testing.py", line 4, in <module>
    print(a)
NameError: name 'a' is not defined

其他回答

只是另一种想法。

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

我发现del有用的一个地方是清除for循环中的无关变量:

for x in some_list:
  do(x)
del x

现在你可以确定,如果你在for循环之外使用x,它将是没有定义的。

显式使用"del"也是比将变量赋值为None更好的实践。如果你试图删除一个不存在的变量,你会得到一个运行时错误,但如果你试图将一个不存在的变量设置为None, Python会无声地将一个新变量设置为None,让你想要删除的变量留在原来的位置。所以del会帮助你尽早发现错误

有一次我不得不使用:

del serial
serial = None

因为只使用:

serial = None

没有及时释放串口,无法立即再次打开。 从这一课中,我了解到del的真正意思是:“现在就开始!然后等待直到它完成”这在很多情况下都很有用。当然,你可能有一个system.gc.del_this_and_wait_balbalba (obj)。

当你使用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]

一起避免这一切。