I've been trying to get my head around Python's passing mechanism - pass by object reference. I often find that writing up my own understanding in a narrative fashion is a useful excercise, but think it is only partly correct. Comments and corrections would be most welcome.
In Python, function arguments are passed by value. And that's why you can't change the value of a passed integer: a copy of the integer is made, and you can only alter the copy, not the original.
But you say, if that's true, why am I able to append to a list that's passed into a function? If it's passed by value, then the function should be operating on a copy of the list!
And the answer to that is - and it's a mouthful - the value that's passed is a copy of the variable that contains a reference to your list object. Object references are passed by value.
Say you have myList = [1, 2]. Think of the = as a divider. On the left we have a variable, myList. On the right we have the [1, 2] list itself, somewhere in memory. The variable contains a reference to the thing on the right – its location in memory. When you access the list, you unpack the contents of the variable to retrieve the contained reference, and it's the reference - the object's address - that you use to access the list itself. So, when you pass myList to a function, you're passing a copy of the variable – which is a container for the reference really. Of course, as it was passed by value, the copy contains the same reference, so you can also access the list in your function. In this situation you had two variables, the original and the one you received in the function; each containing the same value – the reference.
So what happens in the integer scenario that makes it different?
In Python, integers aren't exactly like the objects we talk about in Object Oriented Programming; really, we can regard them as just blobs of data, with none of the properties we associate with objects in our OO world: they're not instantiated in the same way as an object defined in a class ; they have no self-reference; and they cannot have functional attributes (methods). So it's perhaps too easy, and arguably wrong, to talk about integer objects in Python. In any case, it's certainly confusing things semantically!
So what is a Python integer? Well, if you have a C background, you'll know all about the 'struct'; which is exactly how integers are manifested in Python:
typedef struct { PyObject_HEAD long ob_ival; } PyIntObject;
And, if you have no C (or C-derivative background), you can more-or-less consider integers to be pieces of integer-sized memory directly (ignoring PyObject).
Now, remember once again, that Python uses pass-by-value, so when passing an integer, you're passing a copy of a 'struct' - or a piece of memory - that contains the integer's actual value (it is in ob_ival), and not something that contains a reference to something somewhere else in memory. Now, when you assign a value to an integer that's passed to a function, you're altering your own private copy of ob_ival, and not the original.