Assigment in C sense does not exist: name binding
Whether Python has "variables" depends on your perspective. Python
certainly does *not* have variables with anything like the semantics of
C/C++ variables. For that reason, it's often convenient to shift the
vocabulary to avoid misunderstading. However, the vast majority of
Python programmers do use "variable" in casual conversation (I certainly
do); it's only when trying to discuss the Python object model that
there's a strong tendency to switch to using "names".
Since all "variable" names in Python are references to objects, anything accessed using a name is accessed by reference?
Anybody using the terms variable, reference or call-by-value is most likely explaining Python the wrong way
http://effbot.org/zone/python-objects.htm (name - binding to value of some type)
http://effbot.org/zone/call-by-object.htm - "call by sharing"
But you must be careful about what is meant by "changes to parameters". Assigning a new value to a parameter name (inside the function, a parameter is just a local variable) does not change the original object--it only rebinds the local variable to a new object.
In the following function, a is rebound with an assignment statement, while b is mutated, i.e., changed, with an assignment statement.
def f(a, b):
a = 12
b.value = 14
Argument a will never be changed, while argument b will be. Python's argument passing semantics are extremely simple. It's the assignment statement that's tricky: some assignments mutate/change objects, and some only rebind names.
x = y = x = 3 # works: <==> (x, y, z) = (3, 3, 3)
and if x=read(): # set-and-test, does not work
(in C, x = y = 3: '=' is operator which returns value, assignment is side effect)
but name binding in Python (and binding to container
items too) doesn't "return a value".
Since Python objects, names, their operations, and the syntax used
for it resemble very closely (but not completely) what is called
"variable" in other languages, Python names are mostly called
"variables", too.
But there is this one thing of changing mutable objects which may
also change the "value" of other "variables". This can only be
understood if your nomenclature is strictly correct.
Python has "variables". It's just sometimes a good advice for people
coming from languages like C to forget about that term for a while because
they have the wrong impression of what "variable" means. A "variable" in
programming languages is composed of a name, a memory location, possibly a
type and a value. In C-like languages, where you put values in named and
typed "boxes", the memory location and type are attached to the name. In
Python both belong to the value.
Your problem is with the semantic of "modifying". In Python, (re)binding
a name and mutating an object are two very distinct things.
You just can't substitute the term "name" with "variable" and
expect it to behave like in C. Python names are very similar to automatically
dereferenced pointer variables in C++.