[Tutor] pointer puzzlement

Steven D'Aprano steve at pearwood.info
Fri May 8 04:27:52 CEST 2015


On Thu, May 07, 2015 at 12:15:42PM -0700, Jim Mooney Py3.4.3winXP wrote:
> I find this a bit confusing. Since the ID of K remains the same, so it's
> the same object, why isn't it increasing each time. i.e, 20, 30, 40,. I
> understand that it's immutable but doesn't that mean K is created each time
> in local scope so it should have a different ID each time?
> 
> def testid(K=10):
>     K += 10
>     return 'the ID is', id(K), K

You have two questions in there, and they are unrelated.

K does not increase each time, because you throw the result away each 
time and start again.

testid() uses the default of K=10. In the body of the function, K+=10 
adds 10+10 to give 20, and binds that to the local variable K. But it 
doesn't change the default value, which is still 10 (ints being 
immutable, it cannot be changed in place). So when you call testid() the 
second time, the previous value of K is lost and it starts against with 
K=10.


Here is an alternative that does behave like persistent storage from 
call to call:

def testid(K=[10]):
    K[0] += 10
    return 'the ID is', id(K), K


Because the default value is a list, and lists are mutable, so long as 
we *modify* that list, the change will be seen the next time round.


Your second question is why the id() doesn't change. There are at 
least two possible reasons for that:

(1) CPython caches small ints. Because they are used so frequently, 
CPython saves time at the cost of a little bit of memory by using the 
same objects each time, instead of creating them from scratch each time. 
The precise ints which are cached are a private implementation detail 
and subject to change without notice, so don't rely on that.

(2) Python only guarantees that IDs are unique for objects which exist 
at the same time. In other words, Python implementations may re-use IDs. 
Some do not: Jython and IronPython don't re-use IDs, but CPython does. 
So if we have a sequence of events like this:

    (1) create K
    (2) print id(K)
    (3) garbage collect K
    (4) create K again
    (5) print id(K) again

it is possible that the K created in (4) gets the same ID as the one 
created in (1).



-- 
Steve


More information about the Tutor mailing list