[Python-3000] default argument surprises

Bruce Leban bruce at leapyear.org
Wed Aug 27 06:10:16 CEST 2008


There are two issues** here:

(1) def foo(L=[]):
the [] is a single list, not a new list created every time the function is
called.

(2) def foo(L=list()):
the list() is evaluated once when the function is declared.

I think (1) is easy to explain; I find (2) confusing. (**Yes, I realize that
these can be considered the same issue, but I'm speaking here as a person
writing python programs, not designing the language.) On the other hand,
consider this code:

    bar = 1
    def foo(arg=bar):
      print(arg)
    bar = 2
    foo()

I would be very surprised if foo() printed 2 rather than 1. The difference
to my (programmer's) mind is that in this case bar looks like a simple value
and list() looks like a function call. So it's not quite that simple. At
least the way it works now is completely consistent and the code:

    def foo(arg=None):
      arg = bar if arg is None else arg
      arg2 = list() if arg is None else arg

is unambiguous if clumsy.

Now thinking as a language designer, C# has a ?? operator where A??B is
shorthand for (B if A is None else A) except you only have to write A once
and A is only evaluated once. A Pythonesque version of this would be just
"else":

   def foo(arg=None, arg2=None):
      arg = arg else bar
      arg2 = arg2 else list()

And I think that metaphor is easy to read. Chains of else operators can be
useful:

   x = f() else g() else h() else 0

--- Bruce
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-3000/attachments/20080826/d80b85b9/attachment.htm>


More information about the Python-3000 mailing list