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!
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
You should really use the faster `is` to compare against `None`:
if time is None:
do_stuff()