5

I can understand the following definition:

Every object has an identity, a type and a value. 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.

I would assume the above definition works when “something” is created, such as:

>>> a = 0
>>> id(a)
1720438480

But I do not understand:

>>> id(1)
1720438512
>>> b = 1
>>> id(b)
1720438512

I did not create anything yet; so how can the integer “1” have an ID? Does it mean that as soon as I “mention” 1 in the Python Shell, it is assigned to a memory address? Also, does it mean that because the ID never changes during its lifetime, and because my computer has a limited memory, if I repeatedly ask for the id() of unique things, I will eventually get something like “out of memory” message? (It cannot reallocate memory, because the lifetime of others have not ended yet.)

Or, showing my ear from the other way round:

>>> id(something_1)
some unique memory address
>>> id(something_2)
some unique memory address
>>> ...

At which point is the memory reallocated? That is, at which point,

>>> my_variable = something_1
>>> id(my_variable)

will give an ID that is different from id(something_1)?

ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
blackened
  • 861
  • 10
  • 19
  • Note that specifically for small integers, `id`s are reused as per https://stackoverflow.com/questions/6934202/python-intern-for-non-strings. – ivan_pozdeev Sep 13 '18 at 23:04

1 Answers1

8

In general, as soon as you use an integer or a string or any other literal, Python creates a new object in memory for you. It is guaranteed to have the same id for the lifetime of the object, that is, while its reference count is not zero.

When you write something like:

>>> id(1000)
140497411829680

Python creates the integer 1000 and returns its id (the memory address of the object in CPython). After this is done, the reference count of the integer object 1000 is zero and it is deleted. This ensures that you cannot keep filling memory just by writing id(something) (and not binding any variable name to the object).

Typically, you cannot predict when reuse will happen, but in my Python shell it happens quite consistently:

>>> id(1000)
140697307078576
>>> id(1001)
140697307078576
>>> id(1002)
140697307078576
>>> id(1003)
140697307078576

You can see that the same memory address get used again and again when each new integer is created. However, if you prevent the reference count from dropping to zero, you can see that new memory is used instead:

>>> a = 1000
>>> id(a)
140697307078576
>>> b = 1001
>>> id(b)
140697306008368

In CPython, the integers -5 through to 255 are special cases in that they always exist (and so always have the same id during a Python runtime). This is an optimisation to avoid repeated creation and destruction of commonly-used integers.

Alex Riley
  • 169,130
  • 45
  • 262
  • 238
  • Hi Alex. What if there's a virtual memory and the program is swapped in/out many times? Wouldn't it change the physical memory address of the same variable? – stdout Aug 06 '17 at 18:14
  • CPython doesn't use garbage collection to clean out unreferenced objects. **The moment the reference count drops to 0** the object is deleted. So yes, `id(1000)` will create an `int` object with value 1000, the only reference is the stack, `id()` produces a value for that object, the object is cleared from the stack and is deleted immediately because the reference count is now 0. Python does have a garbage collector, but all it is responsible for is to break cyclic references. – Martijn Pieters Aug 24 '17 at 07:04
  • 1
    As for small numbers, the range is [from -5 through to 256](https://stackoverflow.com/questions/306313/is-operator-behaves-unexpectedly-with-integers). – Martijn Pieters Aug 24 '17 at 07:07