Velocity Reviews > Address of an immutable object

# Address of an immutable object

candide
Guest
Posts: n/a

 05-30-2010
Suppose a Python program defines an integer object with value 42. The
object has an "address" we can capture with the built-in function id() :

>>> a=42
>>> id(a)

152263540
>>>

Now I was wondering if any integer object with value 42 will be refered
at the same adress with the above id.

Some experiments tend to show that it may be the case, for instance :

>>> a=42
>>> id(a)

152263540
>>> id(42)

152263540
>>> b=2*21
>>> id(b)

152263540
>>> c=0b101010
>>> id(c)

152263540

>>> d={"foo":42, "bar":"foo"}
>>> id(d["foo"])

152263540
>>> L=["foo",(51,([14,42],5)),"bar"]
>>> id(L[1][1][0][1])

152263540
>>> del a
>>> id(L[1][1][0][1])

152263540

>>> zzz=range(1000)
>>> id(zzz[42])

152263540
>>>

Even you can't make a deep copy :

>>> from copy import deepcopy
>>> a=42
>>> from copy import deepcopy
>>> z=deepcopy(a)
>>> id(a), id(z)

(152263540, 152263540)
>>>

So is the following true :

Two non mutable objects with the same value shall be allocated at a

Alf P. Steinbach
Guest
Posts: n/a

 05-30-2010
* candide, on 30.05.2010 19:38:
> Suppose a Python program defines an integer object with value 42. The
> object has an "address" we can capture with the built-in function id() :
>
> >>> a=42
> >>> id(a)

> 152263540
> >>>

>
> Now I was wondering if any integer object with value 42 will be refered
> at the same adress with the above id.
>
> Some experiments tend to show that it may be the case, for instance :
>
> >>> a=42
> >>> id(a)

> 152263540
> >>> id(42)

> 152263540
> >>> b=2*21
> >>> id(b)

> 152263540
> >>> c=0b101010
> >>> id(c)

> 152263540
> >>> d={"foo":42, "bar":"foo"}
> >>> id(d["foo"])

> 152263540
> >>> L=["foo",(51,([14,42],5)),"bar"]
> >>> id(L[1][1][0][1])

> 152263540
> >>> del a
> >>> id(L[1][1][0][1])

> 152263540
> >>> zzz=range(1000)
> >>> id(zzz[42])

> 152263540
> >>>

>
> Even you can't make a deep copy :
>
>
> >>> from copy import deepcopy
> >>> a=42
> >>> from copy import deepcopy
> >>> z=deepcopy(a)
> >>> id(a), id(z)

> (152263540, 152263540)
> >>>

>
> So is the following true :
>
> Two non mutable objects with the same value shall be allocated at a
> constant and unique address ?

No.

First, id() doesn't generally provide an address. It does that in CPython, but
more generally it just provides a unique integer identifying the reference. You
can think of it as the "reference value" if you want; it's what's copied by an
assignment to a variable.

Second, the reason that you get the same id for various 42 objects is that
CPython uses a cache of "small integer" objects. As I recall the cache ranges
from -5 to some 127 or so (or perhaps it was double that). Any value outside
that cached range you'll see different id's for the same value.

Cheers & hth.,

- Alf

--
blog at <url: http://alfps.wordpress.com>

Simon Brunning
Guest
Posts: n/a

 05-30-2010
On 30 May 2010 18:38:23 UTC+1, candide <(E-Mail Removed)> wrote:
> Two non mutable objects with the same value shall be allocated at a constant and unique address ?

Nope.

>>> a = 999
>>> b = 999
>>> id(a) == id(b)

False

Your statement will be the case for small integers, but this in an
implementation detail. Indeed, this used to be the case for integers
up to 100 (IIRC) or thereabouts, but it's now the case up to 256:

>>> a = 256
>>> b = 256
>>> id(a) == id(b)

True
>>> a = 257
>>> a = 257
>>> id(a) == id(b)

False

Some identifier-like strings are also interned like this:

>>> a = 'foo'
>>> b = 'foo'
>>> id(a) == id(b)

True
>>> a = 'two words'
>>> b = 'two words'
>>> id(a) == id(b)

False

But again, it's an implementation detail, and shouldn't be relied upon.

This same issue also comes up with people noticing that they can
compare small integers with the 'is' operator, and getting a surprise
when bigger numbers come along:

>>> a = 256
>>> b = 256
>>> a is b

True
>>> a = 257
>>> b = 257
>>> a is b

False

--
Cheers,
Simon B.

candide
Guest
Posts: n/a

 05-30-2010
Thanks for your responses, I should do more experiments !

candide
Guest
Posts: n/a

 05-30-2010
Alf P. Steinbach a écrit :
> * candide, on 30.05.2010 19:38:
>> Suppose a Python program defines an integer object with value 42. The
>> object has an "address" we can capture with the built-in function id() :

> First, id() doesn't generally provide an address.

but according to "The Python Language Reference" it's not very far from
the truth :

--------------------
3.1 Objects, values and types
(...)
An object’s identity never changes
once it has been created; you may think of it as the object’s _address_
in memory. The ‘is‘ operator compares the
identity of two objects; the id() function returns an integer
representing its identity (currently implemented as
--------------------

(emphasizing is mine)

Dennis Lee Bieber
Guest
Posts: n/a

 05-30-2010
On Sun, 30 May 2010 22:08:49 +0200, candide <(E-Mail Removed)>
declaimed the following in gmane.comp.python.general:

> but according to "The Python Language Reference" it's not very far from
> the truth :
>
> --------------------
> 3.1 Objects, values and types
> (...)
> An object’s identity never changes
> once it has been created; you may think of it as the object’s _address_
> in memory. The ‘is‘ operator compares the
> identity of two objects; the id() function returns an integer
> representing its identity (currently implemented as
> --------------------

Two key terms: "may THINK of it as" and "currently implemented
as"...

Neither guarantees that it is. The latter, as mentioned, is a detail
of the common C-language implementation.

The ID could be an index into a managed list of addresses pointing
to other items (this is sort of how the old Macintosh "handles" worked:
when you allocated a heap object, you got back a reference (a "handle")
into a fixed table of references; this permitted the garbage collector
to move the actual data objects around in memory [collecting free space
-- defragmenting memory] by updating the handle's reference to point to
the new location of the object -- the user code doesn't have to track
relocations since the location of the handle itself did not change).

--
Wulfraed Dennis Lee Bieber AF6VN
http://www.velocityreviews.com/forums/(E-Mail Removed) HTTP://wlfraed.home.netcom.com/

Steven D'Aprano
Guest
Posts: n/a

 05-30-2010
On Sun, 30 May 2010 22:08:49 +0200, candide wrote:

> Alf P. Steinbach a Ã©crit :
>> * candide, on 30.05.2010 19:38:
>>> Suppose a Python program defines an integer object with value 42. The
>>> object has an "address" we can capture with the built-in function id()
>>> :

>
>> First, id() doesn't generally provide an address.

>
> I talked about a quote unquote "address" but according to "The Python
> Language Reference" it's not very far from the truth :
>
> --------------------
> 3.1 Objects, values and types
> (...)
> An objectâ€™s identity never changes
> once it has been created; you may think of it as the objectâ€™s _address_
> in memory. The â€˜isâ€˜ operator compares the identity of two objects; the
> id() function returns an integer representing its identity (currently
> --------------------
>
> (emphasizing is mine)

Which is a weakness of the documentation, since in Jython object ids are
1, 2, 3, 4, ... rather than addresses in memory. Of course, if you want
to think of 1, 2, 3, 4, ... as addresses, who's going to stop you?

--
Steven