"constant sharing" works differently in REPL than in script ?

S

shearichard

Listening to 'Radio Free Python' episode 8 (http://radiofreepython.com/episodes/8/ - around about the 30 minute mark) I heard that Python pre creates some integer constants to avoid a proliferation of objects with the same value.

I was interested in this and so I decided to try it out.

First I did this at the prompt :
True

So that matched what I'd heard and then I did this to test the limits of it :
False

And that was reasonable too as the podcast mentioned it was only done for a small set of integers around zero.

However when I wrote this script :

c = 259
print id(259)
print id(c)
if c is 259:
print "%s - yes" % (c)
else:
print "%s - no " % (c)

I got this output :

C:\data\src\Python\foo>python untitled-2.py
26760884
26760884
259 - yes

So what's going on here. The script seems to be sharing objects in a way the REPL isn't ?

Can anyone explain please ?

BTW this is all on : Python 2.6.1 (r261:67517, Dec 4 2008, 16:51:00) [MSC v.1500 32 bit (Intel)] on win32 .
 
B

Benjamin Kaplan

Listening to 'Radio Free Python' episode 8 (http://radiofreepython.com/episodes/8/ - around about the 30 minute mark) I heard that Python pre creates some integer constants to avoid a proliferation of objects with the same value.

I was interested in this and so I decided to try it out.

First I did this at the prompt :
True

So that matched what I'd heard and then I did this to test the limits of it :
False

And that was reasonable too as the podcast mentioned it was only done fora small set of integers around zero.

However when I wrote this script :

c = 259
print id(259)
print id(c)
if c is 259:
   print "%s - yes" % (c)
else:
   print "%s - no " % (c)

I got this output :

C:\data\src\Python\foo>python untitled-2.py
26760884
26760884
259 - yes

So what's going on here. The script seems to be sharing objects in a way the REPL isn't ?

Can anyone explain please ?

BTW this is all on : Python 2.6.1 (r261:67517, Dec  4 2008, 16:51:00) [MSC v.1500 32 bit (Intel)] on win32 .

Python the language doesn't specify anything about this sort of
behavior. CPython the implementation does all sorts of optimizations
to make code run more efficiently. Caching integers is one of those
optimizations. In the case where the code is compiled all at once (as
in the script) instead of one line at a time (the REPL), it can do
more optimizations. But as I said, none of this is in the
specification so you shouldn't rely on it. The general rule for the
"is" operator is that unless you specifically know that you need it,
don't use it.
 
C

Chris Angelico

...Python pre creates some integer constants to avoid a proliferation of objects with the same value.

I was interested in this and so I decided to try it out.
So that matched what I'd heard and then I did this to test the limits of it :

And that was reasonable too as the podcast mentioned it was only done for a small set of integers around zero.

The exact set varies according to Python version and, as others have
mentioned, shouldn't be relied upon.

import sys
print(sys.version)
wascached=False
for i in range(-100,300):
j=i+1
j-=1
if (i is j)!=wascached:
wascached=i is j
if wascached:
firstcache=i
else:
print("%d to %d are cached"%(firstcache,i-1))
break

2.4.5 (#1, Jul 22 2011, 02:01:04)
[GCC 4.1.1]
-5 to 99 are cached

2.6.5 (r265:79096, Mar 19 2010, 21:48:26) [MSC v.1500 32 bit (Intel)]
-5 to 256 are cached

3.2 (r32:88445, Feb 20 2011, 21:29:02) [MSC v.1500 32 bit (Intel)]
-5 to 256 are cached

It's definitely something that's fun to play with, though not
something to take ANY notice of in real code :)

ChrisA
 
S

shearichard

Thanks for all the replies. I hadn't thought about the opportunities that exist for optimization when the whole script is there (or when compound operations are taking place) by contrast with plain old REPL ops.

I liked your code Chris demoing the different ranges in different versions. I tried to write something like that myself but you did it an awful lot better !
 
C

Chris Angelico

I liked your code Chris demoing the different ranges in different versions. I tried to write something like that myself but you did it an awful lot better !

There's no guarantee that it'll prove which are and aren't cached, but
it does seem to work. (Incidentally, it doesn't handle the case where
_no_ integers are cached.)

ChrisA
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,525
Members
44,997
Latest member
mileyka

Latest Threads

Top