Section 2: Function Parameters

 Table of Contents > Chapter 5 > Section 2 

As we have seen, functions can have optional parameters and therefore argument lists of varying length.  In this section of the course we look at how to define functions that consume a variable number of arguments.

Default and keyword arguments

It is possible to specify a default value for a parameter when a function is defined.  Suppose, for example, that we want to design a function that draws a rectangle on the screen using individual characters.  So, something along the lines of:

* * *           % % % %

*   *    or     % + + % 

*   *           % % % %

* * *


Note that one character is used to draw the border and another to fill the interior.  In the case of the first rectangle drawn above, the fill character is a space.  On comparing the two rectangles drawn above, we see 4 points of variation: width, height, border character and fill character.  Our function will therefore consume 4 parameters.  One way to define the function is as follows:

def draw_rect(w, h, bc, fc):
   
    """
   
    int, int, str, str -> NoneType

    
   
    Draws a rectangle of width w and height h
   
    with bc for the border and fc for the fill.
   
    """
   
    # body omitted

This requires the caller to pass 4 arguments when the function is called. 

We may, however, decide to provide a default choice for the border and fill characters.  If, for example, we want the default border character to be '*' and the default fill character to be ' ', we define the function in the following way:

def draw_rect(w, h, bc='*', fc=' '):

    """

    int, int, str, str -> NoneType

    
Draws a rectangle of width w and height h

    with bc for the border and fc for the fill.

    """

    # body omitted


The function can now be called in any of the following ways:

>>> # specify values for all parameters

>>> draw_rect(4, 3, 'x','o')

x x x x

x o o x

x x x x

>>> # use default fill character

>>> draw_rect(4, 3, '+')

+ + + +

+     +

+ + + +

>>> # use default border and fill characters

>>> draw_rect(4, 3)

* * * *

*     *

* * * *



But what if we want to specify the fill character but use the default border character?  To do this we use keyword arguments as illustrated below:

>>> # use default border character

>>> draw_rect(4, 3, fc='^')

* * * *

* ^ ^ *

* * * *


So, fc='^' is a keyword argument.  It indicates that the value to be passed to the parameter named fc is '^'.  Note that keyword arguments must follow all non-keyword arguments.  However, within the set of keyword arguments, order doesn't matter.  So, the following call is valid:

>>> # use default border character

>>> draw_rect(4, 3, fc='^', bc='o')

o o o o

o ^ ^ o

o o o o


Notice that the parameters fc and bc are not passed in the same order in which they appear in the function declaration.


Variable-length parameter lists: *args and **kwargs

There is a sense in which the arguments passed to a function can be viewed as a list of values.  So, if we want to specify a value for all the parameters in our draw_rect function, we might think of packaging the arguments into a list [4, 3, '*', '+'] and passing the list as a single argument.  The arguments in the list can then be unpacked using the * operator as illustrated below:

>>> args = [4, 3, '*', '+']

>>> draw_rect(*args)

* * * *

* + + *

* * * *



You might also be thinking that the keyword arguments look rather like key-value pairs in a dictionary.  Indeed, these arguments can be wrapped in a dictionary and unpacked using the ** operator when passed to the function:

>>> args = [4, 3]

>>> kwargs = dict(bc='*', fc='+')

>>> draw_rect(*args, **kwargs)

* * * *

* + + *

* * * *


When reading documentation for Python functions, you might see *args and/or **kwargs used to specify a parameter list.  In such cases, the function documentation must carefully specify the parameters that can be passed.