Address of an immutable object

Discussion in 'Python' started by candide, May 30, 2010.

  1. candide

    candide Guest

    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 ?
     
    candide, May 30, 2010
    #1
    1. Advertising

  2. * 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>
     
    Alf P. Steinbach, May 30, 2010
    #2
    1. Advertising

  3. On 30 May 2010 18:38:23 UTC+1, candide <> 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.
     
    Simon Brunning, May 30, 2010
    #3
  4. candide

    candide Guest

    Thanks for your responses, I should do more experiments !
     
    candide, May 30, 2010
    #4
  5. candide

    candide Guest

    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 implemented as
    its _address_).
    --------------------

    (emphasizing is mine)
     
    candide, May 30, 2010
    #5
  6. On Sun, 30 May 2010 22:08:49 +0200, candide <>
    declaimed the following in gmane.comp.python.general:


    > 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 implemented as
    > its _address_).
    > --------------------


    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://wlfraed.home.netcom.com/
     
    Dennis Lee Bieber, May 30, 2010
    #6
  7. 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
    > implemented as its _address_).
    > --------------------
    >
    > (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
     
    Steven D'Aprano, May 31, 2010
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. hiwa
    Replies:
    22
    Views:
    7,026
    Lasse Reichstein Nielsen
    Apr 5, 2005
  2. Mapisto
    Replies:
    6
    Views:
    480
    Magnus Lycka
    Oct 20, 2005
  3. Replies:
    2
    Views:
    647
    John Harrison
    Nov 17, 2005
  4. Mize-ze
    Replies:
    2
    Views:
    348
    Hendrik Maryns
    Apr 2, 2007
  5. visionset

    Immutable object graph

    visionset, May 24, 2007, in forum: Java
    Replies:
    12
    Views:
    648
Loading...

Share This Page