1

Suppose I have this code:

myInt = 5
myInt = 7
myInt2 = 5

Integers are immutable so when line 2 runs Python stops pointing to address memory where 5 is stored and starts pointing to where 7 is stored. BUT 5 value is still there but nobody is pointing at it.

  1. So how does Python know where to point when line 3 is run?
  2. Does it go through all memory blocks, or addresses, until it finds value 5?
  3. Or does it keep separated, in memory, a cache or a table where un-referenced values are stored?

Thank you!

wjandrea
  • 28,235
  • 9
  • 60
  • 81
totito88
  • 19
  • 4
  • 1
    It is implementation-dependent whether 5 is cached at all or if a new instance of 5 is created for line 3. Likewise, the method of garbage collection used is also implementation-dependent. – chepner Nov 09 '19 at 19:25
  • I'd need to look at the python source to know for sure, but my assumption would be that for an `int` variable it just stores the value rather than a reference (they're the same size anyway, and storing a value is a lot less bookkeeping). – Samwise Nov 09 '19 at 19:25
  • 3
    @SamStafford In Python, even ints are objects and a literal int builds a reference to an object. Python does cache them. It also pre-instantiates the first 100 ints or so. – Keith Nov 09 '19 at 19:27
  • You can have a look at https://stackoverflow.com/questions/306313/is-operator-behaves-unexpectedly-with-integers for an explanation about how small integers are treated. – Thierry Lathuille Nov 09 '19 at 19:31
  • @Keith I read that pre-instantiates from -5 to 256 and stores them in an array! That's why if you a = 255, b = 255, id(a) == id(b) returns True but if you a = 260, b = 260, id(a) == id(b) returns False! I'd love to know what happens with numbers > 256 though! Bare with me guys, Im self-teaching programming and Im grabbing a lot of concepts at the same time. – totito88 Nov 09 '19 at 19:35
  • @ThierryLathuille thx! I'll check that out right know! – totito88 Nov 09 '19 at 19:36

2 Answers2

1

Or does it keep separated, in memory, a cache or a table where un-referenced values are stored?

Your guess above is more or less correct in CPython. There is a small integer intern, whith holds integers -5 to 256 inclusive on a default CPython build. See the macros defined here and here for those exact bounds.

The memory for these small integers is preallocated, so each assignment statement you've shown here retrieves a cached object from the intern. Neither 5 nor 7 will be created nor deleted because they were already interned, and they will remain in the intern until the interpreter exits.

So, assigning to these values will simply increment or decrement their reference counts, as you can check by using stdlib gc module:

>>> import gc
>>> def counts():
...     print("refcount5:", len(gc.get_referrers(5)))
...     print("refcount7:", len(gc.get_referrers(7)))
... 
>>> counts()
refcount5: 10
refcount7: 7
>>> myInt = 5  # this will increment 5's refcount
>>> counts()
refcount5: 11
refcount7: 7
>>> myInt = 7  # this will decrement 5's refcount and increment 7's
>>> counts()
refcount5: 10
refcount7: 8
>>> myInt2 = 5  # this will increment 5's refcount
>>> counts()
refcount5: 11
refcount7: 8

You can see the code which retrieves from intern here:

#define IS_SMALL_INT(ival) (-NSMALLNEGINTS <= (ival) && (ival) < NSMALLPOSINTS)

...

PyObject *
PyLong_FromLong(long ival)
{
    ...

    if (IS_SMALL_INT(ival)) {
        return get_small_int((sdigit)ival);
    }
    ...
}

Note that interning integers is an implementation detail.

wim
  • 338,267
  • 99
  • 616
  • 750
  • It depends - usually new objects will be created/destroyed, unless [Python's peephole optimizer is able to determine that an identical object can be safely reused](https://stackoverflow.com/q/55347581/674039). – wim Nov 09 '19 at 20:08
  • Thank you @wim you're answer is awesome! Although reading code at this early stage of my learning, and C code the most, is difficult. I don't know how to choose it best answer but keep it in mind!!! – totito88 Nov 09 '19 at 20:37
0

In python heap structure is maintain memory and all the things are object

ex a=5 here 5 is store in memory location and a is pointer to it.

so if you do b=5 then hex(id(a))==hex(id(b)), both object point to same memory location.

so interface is like this

python object -- pointer module -- > actual memory location

so if you change value of a , say a=53 then check hex(id(a)) then you will find it is different then before but object is same. so we can say new mmory location is done, middle ware python object allocation (dont know offically what it is called) handle the assignment(binding) to new memory location and the object (a)

now question how long it maintain the unassigned value of 5 in memory, it all depends on heap size how much grabage allocator can store , c apis

sahasrara62
  • 10,069
  • 3
  • 29
  • 44