Optional arguments in Python
7 March 2008
Optional arguments in Python are obviously very useful allowing you to have default values so you don’t need to pass them every time. A simple hello world example always goes a long way…
def hello(to="world"):
print "Hello,", to
>>> hello("Steve")
Hello, Steve
>>> hello()
Hello, world
Sometimes you’ll see people define an optional argument with a default value of None then override it in the function’s body. This might seem a strange thing to do at first, but there is a reason. Let’s say that we wanted to be able to say hello to a list of people and for it to automatically add “World” to the list.
def hello(to=[]):
to.append("World")
if len(to) > 1:
greeting = "Hello, " + ", ".join(to[:-1]) + " and " + to[-1]
else:
greeting = "Hello, " + to[0]
print greeting
>>> hello(["Steve", "Matt"])
Hello, Steve, Matt and World
>>> hello(["Steve", "Matt"])
Hello, Steve, Matt and World
>>> hello()
Hello, World
>>> hello()
Hello, World and World
>>> hello()
Hello, World, World and World
This happens because the value for the default argument is the same list every
time, so when we modify it the function has the same modified list as the
default argument when it is subsequently called. This is probably not the
behaviour you would expect and you would rarely want to use this behaviour. The
way around it is to define the default argument as None
then override it.
def hello(to=None):
if to is None:
to = []
to.append("World")
if len(to) > 1:
greeting = "Hello, " + ", ".join(to[:-1]) + " and " + to[-1]
else:
greeting = "Hello, " + to[0]
print greeting
>>> hello()
Hello, World
>>> hello()
Hello, World
>>> hello(["Steve", "Matt"])
Hello, Steve, Matt and World
>>> hello(["Steve", "Matt"])
Hello, Steve, Matt and World
By setting to
to []
at run time the list is a new list each time the
function is run. Previously the list was created when the function was defined,
meaning the same list was appended to.