Why doesn't del do the same thing?

无人久伴 提交于 2019-12-13 00:49:58

问题


Why does the following code change both variables:

>>> a = []
>>> b = a
>>> a.append(9)
>>> a
[9]
>>> b
[9]
>>> 

But the del statement does not achieve the same effect?

>>> a = []
>>> b = a
>>> del(a)
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> b
[]
>>> 

回答1:


When you do:

a = b

What you're doing is assigning the label b to the same object that the label a is refering to.

When you do:

a.append(9)

You're adding 9 to the list object pointed to by both a and b. It's the same object, so they show the same result.

When you do:

del a

You're deleting the reference to the object, not the object itself. If it's the only reference, then the object will be garbage collected. But in your case, there's another reference - b - so the object continues to exist.




回答2:


Instead of "variables", think in terms of names and objects.

>>> a = []

This makes an empty list object and binds the name a to it.

>>> b = a

This simply says that b is now a new name for the object named by a. We have

>>> a is b
True

del a means that we're forgetting the name a: it is no longer bound to an object.

>>> del a
>>> a
Traceback (most recent call last):
  File "<ipython-input-8-60b725f10c9c>", line 1, in <module>
    a
NameError: name 'a' is not defined

But that you're no longer calling that list object a, only b, doesn't affect the object itself in any way. Objects don't care, or even know about, what names you've given them. [One semi-exception is that if an object no longer has any references, it may -- or may not, no promises -- be garbage-collected.]




回答3:


The append method works against the actual object, while del works against the reference i.e. variable name.




回答4:


(I already answered the question in the other question of yours, so I'm going to use it here as well, with slight modifications:)

del does not delete objects; in fact in Python, it is not even possible to tell the interpreter/VM to remove an object from memory because Python is a garbage collected language (like Java, C#, Ruby, Haskell etc).

Instead, what del does when called on a variable (as opposed to a dictionary key or list item) like this:

del a

is that it only removes the local (or global) variable not what it points to (every variable in Python holds a pointer/reference to its contents not the content itself). In fact, since locals and globals are stored as a dictionary under the hood (see locals() and globals()), del a is equivalent to:

del locals()['a']

(or del globals()['a'] when applied to a global.)

so if you have:

a = []
b = a

you're making a list, storing a reference to it in a and then copying that reference into b without copying/touching the list object itself. Therefore these two calls affect one and the same object:

>>> 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 returns the memory address of an object)

whereas deleting b is in no way related to touching what b points to:

>>> a = []
>>> b = a
>>> del b  # a is still untouched and points to a list
>>> b
NameError: name 'b' is not defined
>>> a
[]


来源:https://stackoverflow.com/questions/23377478/why-doesnt-del-do-the-same-thing

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!