Python uses pass-by-value, but since all such values are object references, the net effect is something akin to pass-by-reference. However, Python programmers think more about whether an object type is mutable or immutable. Mutable objects can be changed in-place (e.g., dictionaries, lists, user-defined objects), whereas immutable objects can't (e.g., integers, strings, tuples).
The following example shows a function that is passed two arguments, an immutable string, and a mutable list.
>>> def do_something(a, b):
... a = "Red"
... b.append("Blue")
...
>>> a = "Yellow"
>>> b = ["Black", "Burgundy"]
>>> do_something(a, b)
>>> print a, b
Yellow ['Black', 'Burgundy', 'Blue']
The line a = "Red"
merely creates a local name, a
, for the string value "Red"
and has no effect on the passed-in argument (which is now hidden, as a
must refer to the local name from then on). Assignment is not an in-place operation, regardless of whether the argument is mutable or immutable.
The b
parameter is a reference to a mutable list object, and the .append()
method performs an in-place extension of the list, tacking on the new "Blue"
string value.
(Because string objects are immutable, they don't have any methods that support in-place modifications.)
Once the function returns, the re-assignment of a
has had no effect, while the extension of b
clearly shows pass-by-reference style call semantics.
As mentioned before, even if the argument for a
is a mutable type, the re-assignment within the function is not an in-place operation, and so there would be no change to the passed argument's value:
>>> a = ["Purple", "Violet"]
>>> do_something(a, b)
>>> print a, b
['Purple', 'Violet'] ['Black', 'Burgundy', 'Blue', 'Blue']
If you didn't want your list modified by the called function, you would instead use the immutable tuple type (identified by the parentheses in the literal form, rather than square brackets), which does not support the in-place .append()
method:
>>> a = "Yellow"
>>> b = ("Black", "Burgundy")
>>> do_something(a, b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in do_something
AttributeError: 'tuple' object has no attribute 'append'