Function attributes: a bug?
Roel Mathys
Roel.Mathys at yucom.be
Sat Mar 29 03:10:31 EST 2003
Default arguments are evaluated once. So if you call afterwards the
function these arguments aren't re-evealuted again.
For mutable objects, like lists, dicts, you get the phenomenon you
encountered.
Typically you should do:
def f( default_arg = None ) :
if default_arg is None :
default_arg = []
...
to circumvent this behaviour.
To make it work with the your functions, you should pass init to the
nested functions:
def make_list_accum( init = None ) :
def accum( elem , init = init ) :
if init is None :
init = []
accum.list = init
accum.list.append( elem )
return accum.list
return accum
which does what you had in mind, I hope.
bye,
roel
Tj wrote:
> Hi,
>
> I'm trying to make a closure using the following code. It returns a
> function that can be used to keep adding stuff to a list.
>
> def make_list_accum(init=[]):
> def accum(elem):
> accum.list.append(elem)
> return accum.list
> accum.list = init
> return accum
>
> But there's a bug -- if I generate a function using this, use it for a
> while to build up a list, then call make_list_accum() again, it will
> want to init itself with the other list by default, sharing it! This
> is surprising behavior, and doesn't happen if I don't use this
> optional init form.
>
> Any thoughts?
>
> BTW, I want to send something like this to Paul Graham for his closure
> shootout. Is this better than the normal version which uses objects?
>
> Tj
More information about the Python-list
mailing list