Argument-Passing in Python

In Python the argument passing refers to the way objects are sent to functions as inputs. Arguments are also known as parameters.

Arguments are passed by assignment. These are the main points in passing arguments to functions:

  • Arguments are passed by automatically assigning objects to local variable names.
  • Assigning to argument names inside a function does not affect the caller.
  • Changing a mutable object argument in a function may impact the caller.
  • Immutable arguments are effectively passed “by value”. For example, integers and strings are passed by object reference instead of by copying.
  • Mutable arguments are effectively passed “by pointer”. For example, lists and dictionaries are also passed by object reference. Mutable objects can be changed in place in the function.

Python’s argument-passing mode involves just the assignment of objects to names, and it works the same on mutable and immutable objects.

Example:

>>> def my_func(a):
...     a = 5
... 
>>> b = 4
>>> my_func(b)
>>> print(b)
4

The variable a is assigned the object 88 when f(b), but since a is defined inside the function my_func(), it lives only within the called function. Changing a inside the function has no effect on the place where the function is called; it just resets the local variable a to a completely different object.

In-place changes to mutable objects live on after a function exits, so they impact callers.

Example:

>>> def my_func(a, b):
...     a = 5
...     b[1] = 'DAN'
... 
>>> c = 4
>>> d = [0, 2]
>>> my_func(c, d)
>>> c, d
(4, [0, 'DAN'])

The my_func function assigns values to argument a and to a component of the object referenced by argument b.
The a variable is a local variable name in the function’s scope, therefor it has no effect on the caller (as in the prior example).

The argument b is also a local variable name but it is passed a mutable object, therefor the result of the assignment to b[1] in the function impacts the value of d after the function returns. It basically changes part of the object that b currently references.

Here you have two very simple examples to illustrate what is said above. First example with immutable objects and the second with mutable objects.

Example 1- Immutable objects

>>> a = 1
>>> b = a
>>> b = 2
>>> print(a)
1

Example 2- Mutable objects

>>> my_list = [1, 2, 3]
>>> x = my_list
>>> x[0] = 'DAN'
>>> print(my_list)
['DAN', 2, 3]

If you want to avoid in-place changes within functions then you can simply make explicit copies of mutable objects:

>>> my_list = [1, 2, 3]
>>> my_func(x, my_list[:])

You can also copy within the function itself if you don’t want to change passed-in objects:

>>> def my_func(a, b):
...     b = b[:]
...     a = 5
...     b[1] = 'DAN'

Note:
These changes prevent impacting the caller; they don’t stop the function from changing the object!

You can use return statement to send back an object or multiple values packed in a tuple or other collection type. We can return tuples and assign the result to the original argument name in the caller:

>>> def motorbikes(a, b):
...     a = 'Honda'
...     b = ['Yamaha', 'Suzuki']
...     return a, b
... 
>>> car1 = 'Audi'
>>> car2 = ['Renaul', 'Fiat']
>>> car1, car2 = motorbikes(car1, car2)
>>> car1, car2
('Honda', ['Yamaha', 'Suzuki'])

Leave a Reply