Quantcast
Channel: Hacker News
Viewing all articles
Browse latest Browse all 25817

Weird Python Integers

$
0
0

Note: all of this code was run on my machine using Python 3.6.1. Not everything will work the same if you test using Python 2.

>>>a=42>>>b=42>>>aisbTrue>>>a=316>>>b=316>>>aisbFalse

That is suprising! It turns out that all “small integers” with the same value point to the same memory. We can use the Python built-in function id which returns a value you can think of as a memory address to investigate.

>>>a=128>>>b=256>>>id(a)4504844960>>>id(b)4504849056>>>(id(a)-id(b))/(a-b)32.0

It looks like there is a table of tiny integers and each integer takes up 32 bytes.

>>>x=1000>>>y=2000>>>id(x)4508143344>>>id(y)4508143312>>>id(x)-id(y)32

It looks like integers that aren’t in the small integers table also take up 32 bytes. The id for these is way larger than for the small integers which means they are stored somewhere else.

>>>id(x)-id(256)3294288

What happens if we change the value of an integer in this table? Python has a module called ctypes that can be misused to directly edit memory. (We could also use a debugger but this way all the examples are in Python.)

>>>importctypes>>>>>>defmutate_int(an_int,new_value):...ctypes.memmove(id(an_int)+24,id(new_value)+24,8)...>>>a_number=7>>>another_number=7>>>mutate_int(a_number,13)>>>a_number13>>>another_number13

Not only have we changed a_number and another_number but all new references to 7:

>>>foriinrange(0,10):...print(i)...01234561389

Even doing math with 7 no longer works correctly 🎉

>>>713>>>6+113>>>7+114>>>(7+1)-113>>>7*226>>>0b1111^0b100013

P.S. You can read more about the table of small integers in the CPython source code.


Viewing all articles
Browse latest Browse all 25817

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>