【发布时间】:2016-03-18 14:51:47
【问题描述】:
如果通过设置清除变量,性能或内存是否有明显差异
x = 'something'
x = None
相对
x = 'something'
del x
对于许多变量?
【问题讨论】:
-
内存没有区别。性能您可以自己检查。
标签: python python-2.7
如果通过设置清除变量,性能或内存是否有明显差异
x = 'something'
x = None
相对
x = 'something'
del x
对于许多变量?
【问题讨论】:
标签: python python-2.7
将变量设置为 None 或将其删除都会导致对对象 x 的引用被释放。主要区别在于 x = None 名称 x 仍然存在,即使它现在指向不同的对象 (None)。使用del 时,名称也会被删除。
对于垃圾收集器,没有区别。 del 不会强制对引用对象进行任何垃圾回收。
编辑:正如@Viroide 指出的那样,使用del 会导致在尝试调用变量x 时引发异常。
【讨论】:
gc.collect()将强制垃圾收集器释放未引用的内存。我不知道显式释放单个变量的方法,我怀疑这种方法是否存在。
两次'something' 的内存都将被回收如果 x 是对该字符串对象的最后引用。在第一个示例中,您使用了更多的内存,因为您保留了名称 x。
我做了一些搜索,看起来内存将立即被回收:further reading。
有一个概念上的差异,但是,你的程序会有不同的行为。当您del x 时,您取消绑定名称x,并尝试使用该名称将引发NameError:
>>> x = 'something'
>>> del x
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
当您设置x = None 时,您重新绑定 x 为对象None 的名称,并且仍然可以按预期使用该变量。例如真/假测试:
>>> x = None
>>> if not x:
... print('hello cshin9!')
...
hello cshin9!
【讨论】:
我很好奇,所以我决定通过运行这段代码来看看模块 dis 的内容:
import dis
def f():
v = 'x'
v = None
del v
return None
print(dis.dis(f))
结果是
4 0 LOAD_CONST 1 ('x')
3 STORE_FAST 0 (v)
5 6 LOAD_CONST 0 (None)
9 STORE_FAST 0 (v)
6 12 DELETE_FAST 0 (v)
7 15 LOAD_CONST 0 (None)
18 RETURN_VALUE
文档说DELETE_FAST
删除本地
co_varnames[var_num]。
将
co_consts[consti]推入堆栈。
因此,就操作/内存而言,LOAD_CONST 执行两项操作(其中一项正在使用内存),我认为只有当您拥有大量元素(而不仅仅是一个)时它才会变得相关 - 因此您可能想使用del。
这也解释了为什么您不能再访问变量 v(因为它已从命名空间中删除,而 LOAD_CONST 只是另一个赋值)。
【讨论】:
这两个语句在当前命名空间上的操作方式有所不同:前者只是更改变量的值,而del 则完全删除变量。 x 指向的先前值无论如何都会被垃圾回收。
性能差异(如果有)可以忽略不计。
【讨论】:
不,不一样,看下面的例子:
x = "something"
x = None
type(x)
<type 'NoneType'>
z = "asd"
del z
type(z)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'z' is not defined
设置为 None 使变量值为 None 并具有 NoneType。但是删除变量会使变量无法通过从上下文中删除来访问。
【讨论】: