[Tutor] Object references and garbage collection confusion

Steven D'Aprano steve at pearwood.info
Tue May 5 20:00:17 CEST 2015


On Tue, May 05, 2015 at 12:29:59AM -0400, Brandon D wrote:
> Hello tutors,
> 
> I'm having trouble understanding, as well as visualizing, how object
> references work in the following situation.  For demonstration purposes I
> will keep it at the most rudimentary level:
> 
> x = 10
> 
> x = x ** x


In the first case statement, Python creates the integer object 10, and 
binds it to the name 'x'. From this instant onwards, x will resolve as 
the int 10.

When the second line executes, Python first evaluates the right hand 
side 'x ** x'. To do this, it looks up the name 'x', which resolves to 
10. It then evaluates 10**10, which creates the int 10000000000, and 
binds that to the name 'x'. From this instant, x now resolves as the new 
value 10000000000.

Immediately afterwards, Python sees that the int 10 is no longer in use. 
(Well, in principle -- in practice, things are more complicated.) Since 
it is no longer in use, the garbage collector deletes the object, and 
reclaims the memory.

That, at least, is how it works in principle. In practice, Python may 
keep a cache of small integers, so that they never get deleted. That 
makes things a bit faster, at the cost of a tiny amount of extra memory. 
But this will depend on the version and implementation of Python. For 
example, some versions of Python cached integers 0 to 100, others -1 to 
255, very old versions might not cache any at all. As a Python 
programmer, you shouldn't care about this, it is purely an optimization 
to speed up the language.


> If my knowledge serves me correctly, Python destroys the value once
> reassigned.  So, how does x = x +  1 work if it's destroyed before it can
> be referenced?  The only solution I came up with is that the two operands
> are evaluated before storing it in the variable,

Correct. Let's say x = 10 again, just for simplicity.

Python first evaluates the right hand side: it looks up 'x', which 
resolves to 10. Then it generates the int 1, and adds them together, 
giving 11. Then it binds 11 to the name 'x', which frees up the 
reference to 10, and (in principle) 10 will be deleted.

The right hand side of the equals sign is always fully evaluated before 
any assignments are done. This is why we can swap two variables like 
this:

a = 1
b = 2
a, b = b, a

The third line evaluates b (giving 2) and a (giving 1), and Python then 
does the assignment:

a, b = 2, 1

which is equivalent to a=2, b=1, thus swapping the values.


-- 
Steve


More information about the Tutor mailing list