Empty list as default parameter

Stian Søiland stain at stud.ntnu.no
Sat Nov 22 22:19:58 CET 2003


* Robin Munn spake thusly:
> Look at this, for example:
> 
> 
>     n = 5
>     def f(x = n):
>         return x
>     n = 3
> 
>     print n     # Prints 3
>     print f()   # Prints 5
> 
> Note that the default argument to f() is the value of n when the def
> statement was executed, not the value of n when f() is called.

Wouldn't it be more logical for a programmer that x should evaluate
to '3' inside f()? 

I can't see what is the purpose of binding default variables at
definition time instead of runtime.

I know perfectly well of the "param is None"-trick - and I've used it
far too often. I've never had any use of early binding of default
parameters except when making a remembering-function-for-fun:
    

    >>> def remember(value=None, list=[]):
    ...     if value is None:
    ...         return list
    ...     else:
    ...         list.append(value)
    ...
    >>> remember(1)
    >>> remember("Hello")
    >>> remember()
    [1, 'Hello']

This example is in LISP presented as a way to do object orientation
without extending LISP. In Python it is an example of when you should
used an object instead.    

Default variables should be meant as local names that can be overridden.
 LISP, default variables are evaluated at runtime:


    ; This function just returns a new list, but prints
    ; "New" each time
    [58]> (defun newlist () (print 'New ) ())
    NEWLIST

    ; this function takes an optional parameter mylist, if it
    ; is not supplied, newlist is called and assigned to mylist
    ; The function returns mylist.
    [59]> (defun getlist (&optional (mylist (newlist))) mylist)
    GETLIST

    ; note how newlist() is called
    [60]> (getlist)
    NEW 
    NIL

    ; each time
    [61]> (getlist)
    NEW 
    NIL

    ; but not when the parameter is supplied
    [62]> (getlist ())
    NIL


This does not work in Python:

    >>> def newlist():
    ...     print "New"
    ...     return []
    ... 
    >>> def getlist(mylist=newlist()):
    ...     return mylist
    ... 
    New
    >>> getlist()
    []
    >>> getlist()
    []

As one could see, newlist is called at definition time, and only once. 

I think that default parameters should be evaluated each time the
function is called and the parameter is not supplied. This is a major
change, so it has to be delayed until 3.0 (possibly enabled by
__future__-imports)

-- 
Stian Søiland               Being able to break security doesn't make
Trondheim, Norway           you a hacker more than being able to hotwire
http://stain.portveien.to/  cars makes you an automotive engineer. [ESR]




More information about the Python-list mailing list