为什么以下代码会更改这两个变量:
>>> a = []
>>> b = a
>>> a.append(9)
>>> a
[9]
>>> b
[9]
>>>
但del
语句没有达到同样的效果?
>>> a = []
>>> b = a
>>> del(a)
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> b
[]
>>>
答案 0 :(得分:2)
当你这样做时:
a = b
您正在做的是将标签b
分配给标签a
所引用的同一对象。
当你这样做时:
a.append(9)
您正在将9
添加到a
和b
指向的列表对象中。它是相同的对象,因此它们显示相同的结果。
当你这样做时:
del a
您正在删除对象的引用,而不是对象本身。如果它是 only 引用,那么该对象将被垃圾收集。但在你的情况下,还有另一个引用 - b
- 所以对象继续存在。
答案 1 :(得分:1)
而不是“变量”,请考虑名称和对象。
>>> a = []
这会产生一个空的列表对象,并将名称a
绑定到它。
>>> b = a
这简单地说b
现在是由a
命名的对象的新名称。我们有
>>> a is b
True
del a
表示我们忘记了名称a
:它不再绑定到某个对象。
>>> del a
>>> a
Traceback (most recent call last):
File "<ipython-input-8-60b725f10c9c>", line 1, in <module>
a
NameError: name 'a' is not defined
但是你不再调用列表对象a
,只有b
,不会以任何方式影响对象本身。物体不关心,甚至不知道你给他们的名字。 [一个例外是,如果一个对象不再有任何引用,它可能 - 或可能不会,没有承诺 - 被垃圾收集。]
答案 2 :(得分:0)
append
方法对实际对象起作用,而del
对引用即变量名称起作用。
答案 3 :(得分:0)
(我已经回答了the other question of yours中的问题,所以我也会在这里使用它,稍作修改:)
del
不会删除对象;实际上在Python中,甚至不可能告诉解释器/ VM从内存中删除对象,因为Python是一种垃圾收集语言(如Java,C#,Ruby,Haskell等)。
相反,调用变量(而不是字典键或列表项)时del
执行的操作如下:
del a
是只删除了它所指向的本地(或全局)变量而不是(Python中的每个变量都包含对其内容的指针/引用而不是内容本身)。实际上,由于locals和globals被存储为字典下的字典(请参阅locals()
和globals()
),del a
相当于:
del locals()['a']
(或del globals()['a']
应用于全局。)
所以如果你有:
a = []
b = a
您正在制作一个列表,在a
中存储对它的引用,然后将该引用复制到b
而不复制/触摸列表对象本身。因此,这两个调用会影响同一个对象:
>>> a.append(1)
>>> b.append(2)
>>> a
[1, 2]
>>> b
[1, 2]
>>> a is b # would be False for 2 identical but different list objects
True
>>> id(a) == id(b)
True
(id
返回对象的内存地址)
而删除b
与触及b
指向的内容无关:
>>> a = []
>>> b = a
>>> del b # a is still untouched and points to a list
>>> b
NameError: name 'b' is not defined
>>> a
[]