Python is strictly a call-by-ref language. The author of the blog and many commenter here seem confused. There are two causes:
1. Some objects are immutable.
This makes some calls seem to be call-by-value, but they are not. A simple look at the generated code makes this obvious. Integers, strings, tuples, ... are passed by reference. It's just that you can't mutate the object being passed.
2. The behaviour of the assignment operator is different from most non-functional language.
In Python, assignment never mutate values. It assign a new reference to the 'variable' (i.e. the scoped name). This explains clearly why in functions, you can't mutate an immutable object even though it is passed by reference: assignment merely rebind the argument name to a new value.
That is why when you want to mutate something in a function in Python, your only recourse is to call a function on that object:
i = 4
s = 'George'
l = [ 'me', 'you']
foo (i, s, l)
def foo(a, b, c):
a = 3
b = 'Mark'
c.append( 42 )
c = [ 2, 1 ]
print(i, s, l)
# prints 4, 'George', ['me', 'you', 42]
While Python works by passing object references, it is not call-by-reference as that term is usually understood. Call-by-reference means that assignment within a function will be seen in the calling scope. That does not happen in Python.
Comments
Python is strictly a call-by-ref language. The author of the blog and many commenter here seem confused. There are two causes:
1. Some objects are immutable.
This makes some calls seem to be call-by-value, but they are not. A simple look at the generated code makes this obvious. Integers, strings, tuples, ... are passed by reference. It's just that you can't mutate the object being passed.
2. The behaviour of the assignment operator is different from most non-functional language.
In Python, assignment never mutate values. It assign a new reference to the 'variable' (i.e. the scoped name). This explains clearly why in functions, you can't mutate an immutable object even though it is passed by reference: assignment merely rebind the argument name to a new value.
That is why when you want to mutate something in a function in Python, your only recourse is to call a function on that object:
While Python works by passing object references, it is not call-by-reference as that term is usually understood. Call-by-reference means that assignment within a function will be seen in the calling scope. That does not happen in Python.