Once-only evaluation of default parameter values function definitions

Sean Ross sross at connectmail.carleton.ca
Tue Apr 13 11:59:28 EDT 2004


"Fred Ma" <fma at doe.carleton.ca> wrote in message
news:407B79D7.424F65A1 at doe.carleton.ca...
> From the python tutorial, it's clear that to avoid sharing default
> values between function calls, one has to avoid:
>
>    Example#1
>    ---------
>    def f(a, L=[]):
>        L.append(a)
>        return L
>
> Instead, one should use:
>
>    Example#2
>    ---------
>    def f(a, L=None):
>        if L is None:
>            L = []
>        L.append(a)
>        return L
>


For fun, here's a little hack to work around that:

from copy import deepcopy

def fresh_defaults(f):
   fdefaults = f.func_defaults                         # get f's defaults
   def freshener(*args, **kwds):
      f.func_defaults = deepcopy(fdefaults)  # and keep fresh
      return f(*args, **kwds)                            # between calls
   return freshener

def f(a, L=[]):
    L.append(a)
    return L
f = fresh_defaults(f)   # <= transform f


[snip]
>    print f(1)
>    print f(2)
>    print f(3)
>
> prints
>
>    [1]
>    [1, 2]
>    [1, 2, 3]
>

now prints

[1]
[2]
[3]


Neat.

Of course, it adds indirection and slows down the code... oh well ;)

Welcome to Python,
Sean





More information about the Python-list mailing list