When a del statement is issued:
Not sure what you're asking, as clearly thats what happens...
>>> x Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'x' is not defined >>> x = 10 >>> 'x' in vars() True >>> vars()['x'] 10 >>> del x >>> 'x' in vars() False >>> x Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'x' is not defined
As you can see, Python stores valid identifiers in
locals()... So del essentially removes it from memory, removing it from these data structures as well. So the identifier is no longer valid. It's not like in C where you might free some memory and set the value to
>>> x = 10 >>> def func(): ... global x ... del x ... >>> x 10 >>> func() >>> x Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'x' is not defined >>>
Raymond made a good point when he mentioned that the object itself (read: the actual data in memory that the identifier points too, for lack of a more detailed explanation) is only freed when it's reference count goes to 0. IMO he could have done a better job detailing this in the python interpreter, so I'll have a go at it.
We'll use the ID function to prove this:
Help on built-in function id in module __builtin__: id(...) id(object) -> integer Return the identity of an object. This is guaranteed to be unique among simultaneously existing objects. (Hint: it's the object's memory address.)
Pay attention to whats going on here, you'll see that for immutable types, different values reference the same memory (strings are immutable in python and are interned, which means only one copy of each unique string is stored -- in ruby, symbols are interned strings).
>>> import sys >>> x = 10 # 10 is a common value, probably exists in memory already >>> sys.getrefcount(x) 26 >>> id(x) # memory location of x 140266396760096 >>> y = x >>> id(y) == id(x) True >>> z = 10 >>> id(z) == id(y) == id(x) True >>> sys.getrefcount(y) 28 >>> sys.getrefcount(z) 28 >>> del y, z >>> sys.getrefcount(x) 26 >>> del x >>> x = 'charlie' >>> id(x) 4442795056 >>> y = 'charlie' >>> z = x >>> id(x) == id(y) == id(z) True >>> sys.getrefcount(x) 4 >>> sys.getrefcount(y) 4 >>> sys.getrefcount(z) 4 >>> del y >>> del x >>> sys.getrefcount(z) # will be two because this line is an additional reference 2 >>> id(z) # pay attention to this memory location because this 4442795056 # is the last remaining reference to 'charlie', and >>> del z # when it goes out of scope 'charlie' is removed from >>> # memory. >>> id('charlie') # This has a different memory location because 'charlie' 4442795104 # had to be re-created.
First we set the identifier 'x' == 10, a common integer value. Since 10 is such a common value, it's almost guaranteed that something in the processes memory already has that value. Since integers are immutable in python, we only ever need one copy of each unique value stored in memory. In this case, there are 24 other references to 10 in memory. Setting
x = 10 creates the 25th reference, and calling
sys.getrefcount(x) is the 26th reference (though it quickly goes out of scope). When we set
y = 10 and
z = x, we know that they all point to the same data because they all have the same memory location. Calling
del alters the reference count, but even when all 3 are deleted the integer 10 still exists in memory.
Next we create set
x = 'charlie', followed by
y = 'charlie', and finally
z = x. You can see all of these variables have the same memory address. Once we delete all of these variables there are no more references to
'charlie'. We can verify this by calling
id('charlie') which will produce a different memory address meaning the string did not exist in memory when we called that function.
One more thing to note is the location of
10 in memory.
10 has a significantly higher memory address than Charlie does. This is because they exist in different locations of memory.
'charlie' exists on the heap whereas
10 exists on the stack.
>>> hex(id(10)) # high address, this is on the stack '0x7f9250c0b820' >>> hex(id('charlie')) # lower address, this is on the heap '0x108cfac60