"constant sharing" works differently in REPL than in script ?
Peter Otten
__peter__ at web.de
Tue Jun 19 02:32:25 EDT 2012
shearichard at gmail.com wrote:
> 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 :
>
>>>> c = 1
>>>> print id(1)
> 26906152
>>>> print id(c)
> 26906152
>>>> c is 1
> True
>
> So that matched what I'd heard and then I did this to test the limits of
> it :
>
>>>> c = 259
>>>> print id(259)
> 26167488
>>>> print id(c)
> 26167512
>>>> c is 259
> 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 ?
As Benjamin wrote, this is a compile-time optimization (and you shouldn't
rely on it). You can replicate it on the commandline:
>>> a = 300
>>> b = 300
>>> a is b
False
>>> c = 300; d = 300
>>> c is d
True
Looking under the hood there's only one value for both constants:
>>> import dis
>>> code = compile("x = 300; y = 300", "<nofile>", "exec")
>>> code.co_consts
(300, None)
The generated bytecode is:
>>> dis.dis(code)
1 0 LOAD_CONST 0 (300)
3 STORE_NAME 0 (x)
6 LOAD_CONST 0 (300)
9 STORE_NAME 1 (y)
12 LOAD_CONST 1 (None)
15 RETURN_VALUE
More information about the Python-list
mailing list