[Python-ideas] fixing mutable default argument values

Jim Jewett jimjjewett at gmail.com
Thu Jan 25 15:41:54 CET 2007


On 1/24/07, Jan Kanis <jan.kanis at phil.uu.nl> wrote:
> I don't like new syntax for something like this, but I think the default
> argument values can be fixed with semantic changes (which should not break
> the most common current uses):
>
> What I think should happen is compile a function like this
>
> def popo(x=[]):
>      x.append(666)
>      print x
>
> as if it had read
>
> def popo(x=__default_argument_marker__):
>      if x == __default_argument_marker__:
>          x = []
>      x.append(666)
>      print x

How is this different from the x=None idiom of today?

    def f(inlist=None):
        if inlist is None:
            inlist=[]

The if (either 2 lines or against PEP8) is a bit ugly, but Calvin
pointed out that you can now write it as

    def f(inlist=None):
        inlist = inlist if (inlist is not None) else []

I see  below that you give it slightly different semantics, but I'm
not entirely sure how to tell when those different semantics should
apply (always?  when the variable name is marked with __*__?  When a
specific non-None singleton appears?), or why you would ever want
them.

> When you use variables as default value instead of literals, I think most
> of the time you intend to have the function do something to the same
> object the variable is bound to, instead of the function creating it's own
> copy every time it's called. This behaviour still works with these
> semantics:

> >>> a = []
> >>>def foo(x=[[],a]):
> >>>   x[0].append(123)
> >>>   x[1].append(123)
> >>>   print x
> >>>foo()
> [[123], [123]]
> >>> foo()
> [[123], [123, 123]]
> >>> foo()
> [[123], [123, 123, 123]]

So you're saying that x[1] should be persistent because it (also) has
a name (as 'a'), but x[0] should be recreated fresh on each call
because it doesn't?

-jJ



More information about the Python-ideas mailing list