Skip to content

Default paramater values with python

Default argument values for functions are a nice shortcut in python. They save you from writing many wrapper functions and make the code more readable and also easier to use. They can be used wrong though:

>>> def foo(a=[]):
...     a.append('bar')
...     return a
...
>>> foo()
['bar']
>>> foo()
['bar', 'bar']

Like described in idiomatic python, using a value which is a refenence (like a list, dict or instance) can lead to odd results. This is because the arguments are evaluated at compile time, not at runtime when the function is called! Instead of creating an empty list as one (inexperienced) would suspect, the default value becomes a reference to a list.

This can be nasty when it is used like this:

>>> def bar(time=datetime.now()):
...     print time
...
>>> bar()
2008-09-26 12:32:23.598052
>>> bar()
2008-09-26 12:32:23.598052

Just like in idiomatic Python, this is a good fix:

>>> def bar(time=None):
...     if time == None:
...             time = datetime.now()
...     print time
...

>>> bar()
2008-09-26 12:35:02.258992
>>> bar()
2008-09-26 12:35:03.059305

Instead of the default argument datetime.now(), using None, and later setting the current time instead of None works fine!

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Reddit

{ 2 } Comments

  1. maze | September 26, 2008 at 13:08 | Permalink

    Personally, I like patterns like:

    def bar(time=None):
    time = time or datetime.now()

    Also, for dictionary items/default parameters, you can use:

    defaults = {
    ‘verbose’: True,
    ‘quickfox’: 42,
    }

    def bar(**options):
    settings = defaults
    settings.update(options)

    bar(quickfox=23)

    Just my piece of mind

  2. JK | April 21, 2009 at 16:19 | Permalink

    You should really use the faster `is` to compare against `None`:

    if time is None:
    do_stuff()

Post a Comment

Your email is never published nor shared. Required fields are marked *