Python 您喜欢使用del还是将其重新分配为None(垃圾收集)

Python 您喜欢使用del还是将其重新分配为None(垃圾收集),python,Python,考虑以下代码: if value and self.fps_display is None: self.fps_display = clock.ClockDisplay() elif not value and self.fps_display is not None: self.fps_display.unschedule() # Do this del self.fps_display # or this self.fps_display =

考虑以下代码:

if value and self.fps_display is None:
    self.fps_display = clock.ClockDisplay()
elif not value and self.fps_display is not None:
    self.fps_display.unschedule()
    # Do this
    del self.fps_display
    # or this
    self.fps_display = None
    # or leave both in ?

哪种python清理更好?

垃圾收集没有区别-在这两种情况下,将释放对
self.fps\u display
指向的对象的引用。您应该使用哪一个取决于您是否希望名称仍然存在(尽管现在指向不同的对象,
None
),或者不存在。

您有一个具有属性的对象,
fps\u display

您不应该将属性设置为奇怪的可选属性或有时缺失属性

如果它是一个一级属性——并且合理可见——则必须将其设置为
None
,以释放任何资源。删除该属性令人毛骨悚然,因为该对象现在具有可选属性,并引发了惊人的异常

self.fps_display = None

区别在于,
self.fps_display=None
将释放它引用的任何内容,但保留名称,即使它只是引用None(类型,NoneType)

另一方面,
del self.fps_display
将完全删除名称及其引用的内容。如果此后尝试使用
self.fps\u display
将抛出AttributeError(如果是普通变量,则抛出NameError)

因此在实践中,通过为名称指定None,您仍然可以在表达式中使用该名称,而使用del时,该名称将被完全删除。在第一种情况下,需要几个字节将名称保留在内存中,而在后一种情况下,将完全清除所有内存使用

一些代码可以说明: 输出:
x删除前的值:这里有一些文本,给变量一个合适的大小
删除前的x大小:98字节
删除前的y值:2
删除后的x值:无
删除后的x大小:16字节
删除后的x类型:
仍然可以使用x!
回溯(最近一次呼叫最后一次):
文件“Untitled.py”,第21行,在
print('y value after deletation:{}.format(y))#将抛出NameError(类属性为AttributeError)
名称错误:未定义名称“y”

我通常选择分配给
None
,因为如果self.fps\u display为None比hasattr(self,“fps\u display”)
更容易(也更漂亮)。如果由于某些不同的含义而需要
None
(但是我会使用
省略号来表示“not present”),则会出现异常。因此事实上,del不会直接调用垃圾收集过程,它只会减少refcounter,并将变量挂起在垃圾空间中,以便收集器进行清理?
import sys
import gc

x = 'Some text here to give the variable a decent size'
y = 2
print('x value before deletion: {}'.format(x))
print('x size before deletion: {} bytes'.format(sys.getsizeof(x)))
print('y value before deletion: {}'.format(y))

x = None
del y
gc.collect() # Not really needed, just to show garbage collection has been done hereafter

print('x value after deletion: {}'.format(x))
print('x size after deletion: {} bytes'.format(sys.getsizeof(x))) # A few bytes needed to keep symbol name
print('x type after deletion: {}'.format(type(x)))

if not x:
    print('Can still use x!')

print('y value after deletion: {}'.format(y)) # Will throw NameError (AttributeError in case of class property)
x value before deletion: Some text here to give the variable a decent size
x size before deletion: 98 bytes
y value before deletion: 2
x value after deletion: None
x size after deletion: 16 bytes
x type after deletion: <class 'NoneType'>
Can still use x!
Traceback (most recent call last):
  File "Untitled.py", line 21, in <module>
    print('y value after deletion: {}'.format(y)) # Will throw NameError (AttributeError in case of class property)
NameError: name 'y' is not defined