In a function definition Python allows default values to be specified for arguments. For
example, suppose we have a function that will run a simulation, and the number of steps in
the simulation is one argument that we allow. Also suppose that 1000 steps is a sensible
default value; the value that will be used in the absence of any other information. Then we
We can call the function and optionally specify or not specify the value for
numberSteps. Thus we can do either
or
runSimulation()
In the first case the function is run with the variable numberSteps set to 500; the value
that we specified. In the second case no value is specified, so numberSteps is set to the
default value of 1000. Of course we could explicitly pass in 1000 to the function if we
wanted to.
When using defaulting arguments you have to be cautious when your default value is a
Python object that is mutable, i.e. can be changed internally. This applies to Python lists
and dictionaries, but not things like numbers, text strings or tuples. A potential problem
arises where a default value is mutable because each time the function is called the same
Python object is used; it will not make a new one each time. Consider the following:
def myFunction(parameters=[]):
parameters.append(100)
print(parameters)
myFunction() # Result: [100]
myFunction() # Result: [100, 100]
myFunction() # Result: [100, 100, 100]
Each time the function is run the same parameters list remains and is added to each
time. To avoid this kind of problem, rather than having an empty list as a default value we
use the None object, which is of course immutable, and then define a new empty list as
required.
def myFunction(parameters=None):
if parameters is None:
parameters = []
parameters.append(100)
print(parameters)
myFunction() # Result: [100]
myFunction() # Result: [100]
A function can have any number of non-defaulting (mandatory) and defaulting
arguments, as long as the defaulting ones come last in the definition; so that when we pass
values to the function the mandatory arguments are filled first. Accordingly, if we add
another argument to the runSimulation function which represents, say, the initial
temperature of the simulation, we would do:
def runSimulation(initialTemperature, numberSteps=1000):
In this case initialTemperature does not have a default and must be specified when the
function is called. If the new argument is specified with a default value then it is allowed
to follow the other defaulting arguments, so, for example, we could have:
def runSimulation(numberSteps=1000, initialTemperature=300.0):
You could call the second form of the function above by explicitly stating the values of
numberSteps as 500 and initialTemperature as 400.0:
runSimulation(500, 400.0)
or by stating only the first argument explicitly, i.e. numberSteps as 500, leaving
initialTemperature at the default vale of 300.0:
runSimulation(500)
or just use both default values.
runSimulation()
The question then naturally arises how you can use the default value for numberSteps
but not for initialTemperature, given that the latter is the second argument in the function.
Fortunately, Python allows names to be used for arguments when calling functions, so you
can identify exactly which argument is being passed in. Thus the following is allowed
runSimulation(initialTemperature=400.0)
Here numberSteps is set to the default 1000 and initialTemperature to 400.0.
You can use names for function arguments even if they do not have default values or
even if there is no particular need to; it is a matter of taste, but should be considered if it
adds clarity. Remember that if you use the name for any argument when calling a function
then all subsequent arguments must also use the named syntax. Accordingly, one could
use a named argument at the end:
runSimulation(500, initialTemperature=400.0)
or name both arguments:
runSimulation(numberSteps=500, initialTemperature=400.0)
or use named arguments in reverse order:
runSimulation(initialTemperature=400.0, numberSteps=500)
which are all equivalent to
runSimulation(500, 400.0)
The ability to use any order for named arguments is particularly useful so that you don’t
have to remember the order in which they were defined in the function.
It is generally a good idea as a programmer that if you add arguments to a function
definition that has already been used in various applications then you should add the new
arguments to the end of the function definition and specify default values for all of them.
This way any existing code employing the function continues to work without
modification. (Of course it is another matter if the function has changed what it actually
does.)