Function Arguments

Variable Passing

Python passes variables in a manner called assignment. This means that if an argument is mutable and it is changed in the function, it will change in the caller. If it is immutable it will not be changed even if the function changes its value; a local copy will be made within the function block. If a function changes one of its parameters that is called a side effect.


def side_effect(L,x):
    return None

What is printed in the last line and why? What is L now?

Optional and Keyword Arguments

Arguments whose values are determined from their ordering in the parameter list are called positional variables. Python supports optional and keyword arguments as well. Optional arguments are assigned a default value in the parameter list of the function definition. If an optional argument is not present in the argument list passed by the caller, it takes on its default value; otherwise it is positional.

def func(x,y=0,w=3):
    return x+y-w

We can call this function with


In this example the optional arguments are passed by position as usual. Optional arguments may also be passed by keyword, not position. Any optional/keyword arguments must follow any and all positional arguments in the list; except for that restriction their order does not matter and some may be omitted.


Default values are set only once, when the function is first encountered by the interpreter. Only immutable types should be used as default values.

Args and Kwargs

What if we wanted to pass a number of arguments that might vary, depending on how we wish to use the function? Python has a built-in mechanism to handle this. We use args for a varying number of positional (non-keyword) arguments. If they should be keyword arguments, we use kwargs.

def myvarfunc(arg1, arg2, *args, **kwargs):


def varargs(var1,var2,*args,**kwargs):
    print(f"Positional argument 1 {var1}")
    print(f"Positional argument 2 {var2}")

    print(f"Args are a {type(args)}")
    for arg in args:
        print(f"Variable  argument {arg}")

    print(f"Kwargs are a {type(kwargs)}")
    for kwarg in kwargs:
        print(f"Keyword:Variable {kwargs[kwarg],kwarg}")

varargs(1, 2, 3, 4, 5, 6, 7, a=8, b=9, c=10)

In this context, the asterisk (*) is called the unpacking operator. Python reads the args into a tuple and any kwargs into a dictionary.

Variable-length arguments and keyword arguments are particularly common in packages. Even if you never write a code that uses them, you will almost certainly use them in code. For example, we started our Python adventure with the plot function from Matplotlib. We specified two positional arguments


The plot function actually works through variable-length arguments and keyword arguments. Its true interface looks like

matplotlib.pyplot.plot(*args, scalex=True, scaley=True, data=None, **kwargs)