Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Good uses for mutable function argument default values?

It is a common mistake in Python to set a mutable object as the default value of an argument in a function. Here's an example taken from this excellent write-up by David Goodger:

>>> def bad_append(new_item, a_list=[]):         a_list.append(new_item)         return a_list >>> print bad_append('one') ['one'] >>> print bad_append('two') ['one', 'two'] 

The explanation why this happens is here.

And now for my question: Is there a good use-case for this syntax?

I mean, if everybody who encounters it makes the same mistake, debugs it, understands the issue and from thereon tries to avoid it, what use is there for such syntax?

like image 790
Jonathan Livni Avatar asked Feb 06 '12 09:02

Jonathan Livni


People also ask

What is the benefit of using default parameter argument in a function?

Default Arguments in C++ A default argument is a value provided in a function declaration that is automatically assigned by the compiler if the calling function doesn't provide a value for the argument. In case any value is passed, the default value is overridden.

What is a mutable default argument?

In Python, when passing a mutable value as a default argument in a function, the default argument is mutated anytime that value is mutated. Here, "mutable value" refers to anything such as a list, a dictionnary or even a class instance.

What can be used as a default function argument?

In C++ programming, we can provide default values for function parameters. If a function with default arguments is called without passing arguments, then the default parameters are used. However, if arguments are passed while calling the function, the default arguments are ignored.

Why does Python have mutable default arguments?

Python's default arguments are evaluated once when the function is defined, not each time the function is called (like it is in say, Ruby). This means that if you use a mutable default argument and mutate it, you will and have mutated that object for all future calls to the function as well.


2 Answers

You can use it to cache values between function calls:

def get_from_cache(name, cache={}):     if name in cache: return cache[name]     cache[name] = result = expensive_calculation()     return result 

but usually that sort of thing is done better with a class as you can then have additional attributes to clear the cache etc.

like image 123
Duncan Avatar answered Sep 18 '22 08:09

Duncan


Canonical answer is this page: http://effbot.org/zone/default-values.htm

It also mentions 3 "good" use cases for mutable default argument:

  • binding local variable to current value of outer variable in a callback
  • cache/memoization
  • local rebinding of global names (for highly optimized code)
like image 40
Peter M. - stands for Monica Avatar answered Sep 19 '22 08:09

Peter M. - stands for Monica