Mutable defaults

Chris Angelico rosuav at gmail.com
Wed Feb 10 18:29:54 EST 2021


On Thu, Feb 11, 2021 at 10:17 AM J. Pic <jpic at yourlabs.org> wrote:
>
> > Most of us know of the perils of mutable default values.
>
> And those who don't pay the price.
>
> I wonder what would be the harm in removing them

Define "removing". Most objects in Python are mutable; would that mean
you can no longer use any custom class, or any object at all that has
a __dict__, as a default?

> or doing copy on call by default.

I assume you are referring only to argument defaults, because
copy-on-call for ALL parameters would be ridiculously costly, not to
mention problematic in many ways.

The main problem is that mutable defaults are only very rarely an
issue (for starters, you have to actually mutate the object - just
because it's mutable, that doesn't mean you'll change anything), but
any global "solution" to the "problem" is going to have a very high
global cost. Not every mutable object is copyable. And it would have
to be a deep copy (in case, for instance, the default is a tuple
containing a list), which has even more cost.

Strongly -1 on any proposal to change the defaults.

Now, if you're interested in some kind of proposal for opt-in
late-bound defaults, I think there'd be some value in researching
that. It would probably require language support, but there'd be a few
potential advantages:

1) The function signature would actually say the real default. For
instance, "def flurble(stuff=[]):" shows that the default is a list,
but "def flurble(stuff=None): if stuff is None: stuff = []" doesn't.
2) This could be more flexible than just copying. The default could
simply be an expression that's evaluated at call time, and could even
refer to other arguments (eg "def frob(things, start=0,
stop=len(things)):"), and, again, the displayed signature would show
the real default, instead of some placeholder.
3) It's far cleaner to read a coherent function signature than to have
to read a handful of lines at the top of the function. That's why we
have defaults in the first place.

But this would depend heavily on finding a really good syntax for it.
It's been investigated at times, but no proposal has ever been strong
enough to push forward. Feel free to try a few things out, see if you
can find something that makes sense.

ChrisA


More information about the Python-list mailing list