When you declare an integer variable in C, the variable is assigned a fixed memory location with enough space to hold the type integer. When you then initialize the variable with a value, the value is put into that space.
Take a look at the C code sample below:
Python uses a different approach. When a variable is initialized with an integer value, that value becomes an integer object, and the variable points to it (references the object). Notice that the Python code and the C code have a lot of similarities, but the variable declarations are missing:
Note: Your memory locations might differ.
As you look at the result of the C code, and figure out the difference between the memory locations if int a and int b, you come to the conclusion that they are 4 bytes apart. In fact, an integer in C takes up 4 bytes or 32 bits. The maximum value of a C integer can then be 2^32 = 4,294,967,296 - 1 (-1 since we start with zero for the unsigned integer). If we want to include negative values, then we have to declare a signed (signed is default) integer with values from -2,147,483,648 to + 2,147,483,647. If you limit yourself to a number 9 digits long, you are pretty safe! Sometimes you see long instead of int, they are the same thing. Long is there to distinguish from short int, limited to 16 bits.
Python removes this confusion, there is only the integer object. Does it have any limits? Very early versions of Python had a limit that was later removed. The limits now are set by the amount of memory you have in your computer. If you want to create an astronomical integer 5,000 digits long, go ahead. Typing it or reading it will be the only problem! How does Python do all of this? It automatically manages the integer object, which is initially set to 32 bits for speed. If it exceeds 32 bits, then Python increases its size as needed up to the RAM limit.