为什么不做同样的事情呢?

时间:2014-04-30 00:12:32

标签: python append del

为什么以下代码会更改这两个变量:

>>> 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
[]
>>> 

4 个答案:

答案 0 :(得分:2)

当你这样做时:

a = b

您正在做的是将标签b分配给标签a所引用的同一对象。

当你这样做时:

a.append(9)

您正在将9添加到ab指向的列表对象中。它是相同的对象,因此它们显示相同的结果。

当你这样做时:

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
[]
相关问题