Certainly the way default arguments work with mutable types is not the most
intuitive and I think your complaint has some merit.

However how would you define the following to work:

def foo():
    cons = [set(), [], (),]
    funs = []
    for ds in cons:
        def g(arg:=ds):
            return arg
        funs.append(g)
    return funs

How would you evaluate "ds" in the context of the call?
If it were to have the same observable behavior as def g(arg=ds) except
that you would get "fresh" reference on each invocation you would get the
following:

assert [f() for f in foo()]  == [set(), [], ()]

Note it cannot be a simple syntactic transform because:

class _MISSING: pass
def foo():
    cons = [set(), [], (),]
    funs = []
    for ds in cons:
        def g(arg=_MISSING):
            if arg is _MISSING:
                arg = eval('ds') # equivalent to arg = ds so does not
produce a fresh reference
            return arg
        funs.append(g)
      return funs

assert [f() for f in foo()]  == [(), (), ()]

Granted the way closures work (especially in the context of loops) is also
a pretty unintuitive, but stands as a barrier to easily implementing your
desired behavior.
And even if that wasn't the case we still have the issue that eval('ds')
doesn't give you a fresh reference.

Would it implicitly deepcopy ds?  e.g.:

class _MISSING: pass
def build_g(default):
    def g(arg=_MISSING):
        if arg is _MISSING:
            arg =  deepcopy(default)
        return arg
    return g

def foo():
    cons = [set(), [], (),]
    funs = []
    for ds in cons:
        g = build_g(ds)
        funs.append(g)
      return funs

What if ds doesn't implement __deepcopy__?


On Mon, May 18, 2020 at 7:11 AM Richard Damon <rich...@damon-family.org>
wrote:

> On 5/18/20 9:06 AM, James Lu wrote:
> > "There should be one-- and preferably only one --obvious way to do it."
>
> *obvious*
>
> multiple ways are allowed as long as there is one clear preference.
>
> --
> Richard Damon
> _______________________________________________
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/PCAVU6BEI4KUYUUVL7F3CKV2EQ7ZPBPK/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/YE77WSNCGMLNVCTTD472WFWAELURMHSF/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to