Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #8475 > unrolled thread

Default value for optional parameters unexpected behaviour?

Started byMarc Aymerich <glicerinu@gmail.com>
First post2011-06-26 11:28 -0700
Last post2011-06-26 15:23 -0400
Articles 7 — 6 participants

Back to article view | Back to comp.lang.python


Contents

  Default value for optional parameters unexpected behaviour? Marc Aymerich <glicerinu@gmail.com> - 2011-06-26 11:28 -0700
    Re: Default value for optional parameters unexpected behaviour? Shashank Singh <shashank.sunny.singh@gmail.com> - 2011-06-27 00:09 +0530
    Re: Default value for optional parameters unexpected behaviour? Corey Richardson <kb1pkl@aim.com> - 2011-06-26 14:36 -0400
    Re: Default value for optional parameters unexpected behaviour? Noah Hall <enalicho@gmail.com> - 2011-06-26 19:45 +0100
    Re: Default value for optional parameters unexpected behaviour? Terry Reedy <tjreedy@udel.edu> - 2011-06-26 14:46 -0400
    Re: Default value for optional parameters unexpected behaviour? Benjamin Kaplan <benjamin.kaplan@case.edu> - 2011-06-26 12:21 -0700
    Re: Default value for optional parameters unexpected behaviour? Corey Richardson <kb1pkl@aim.com> - 2011-06-26 15:23 -0400

#8475 — Default value for optional parameters unexpected behaviour?

FromMarc Aymerich <glicerinu@gmail.com>
Date2011-06-26 11:28 -0700
SubjectDefault value for optional parameters unexpected behaviour?
Message-ID<2a25a54a-c60b-4811-9c6a-97c7f717dccb@hd10g2000vbb.googlegroups.com>
Hi,
I'm trying to define a function that has an optional parameter which
should be an empty list whenever it isn't given. However, it takes as
value the same value as the last time the function was executed. What
is the reason of this behaviour? How does python deal with default
values (i.e. when are they assigned/created)?

Thanks :)

>>> def a(foo=[]):
...  foo.append(1)
...  print foo
...
>>> a()
[1]
>>> a()
[1, 1]
>>> a()
[1, 1, 1]
>>> a()
[1, 1, 1, 1]
>>> a()
[1, 1, 1, 1, 1]
>>> a()
[1, 1, 1, 1, 1, 1]

[toc] | [next] | [standalone]


#8476

FromShashank Singh <shashank.sunny.singh@gmail.com>
Date2011-06-27 00:09 +0530
Message-ID<mailman.424.1309113580.1164.python-list@python.org>
In reply to#8475
On Sun, Jun 26, 2011 at 11:58 PM, Marc Aymerich <glicerinu@gmail.com> wrote:
> Hi,
> I'm trying to define a function that has an optional parameter which
> should be an empty list whenever it isn't given. However, it takes as
> value the same value as the last time the function was executed. What
> is the reason of this behaviour? How does python deal with default
> values (i.e. when are they assigned/created)?

This has been discussed before in this list, quite a few times
http://mail.python.org/pipermail/python-list/2010-March/1239044.html

A solution is to accept default value as None assign to [] by checking
for None inside the function

def f(a=None):
  if a is None: a = []



-- 
Regards
Shashank Singh
http://rationalpie.wordpress.com

[toc] | [prev] | [next] | [standalone]


#8478

FromCorey Richardson <kb1pkl@aim.com>
Date2011-06-26 14:36 -0400
Message-ID<mailman.426.1309113702.1164.python-list@python.org>
In reply to#8475

[Multipart message — attachments visible in raw view] — view raw

Excerpts from Marc Aymerich's message of Sun Jun 26 14:28:30 -0400 2011:
> Hi,
> I'm trying to define a function that has an optional parameter which
> should be an empty list whenever it isn't given. However, it takes as
> value the same value as the last time the function was executed. What
> is the reason of this behaviour? How does python deal with default
> values (i.e. when are they assigned/created)?
> 
> Thanks :)
> 

Really common mistake, I made it myself too. When Python evaluates the 
function, it sees the default parameter of `foo' as the new object you
create with []. It keeps that object around. The proper idiom instead of

> >>> def a(foo=[]):
> ...  foo.append(1)
> ...  print foo
> ...

is

def a(foo=None):
	if foo is None:
		foo = []
	foo.append(1)
	print foo
-- 
Corey Richardson
  "Those who deny freedom to others, deserve it not for themselves"
     -- Abraham Lincoln

[toc] | [prev] | [next] | [standalone]


#8479

FromNoah Hall <enalicho@gmail.com>
Date2011-06-26 19:45 +0100
Message-ID<mailman.427.1309113933.1164.python-list@python.org>
In reply to#8475
On Sun, Jun 26, 2011 at 7:28 PM, Marc Aymerich <glicerinu@gmail.com> wrote:
> Hi,
> I'm trying to define a function that has an optional parameter which
> should be an empty list whenever it isn't given. However, it takes as
> value the same value as the last time the function was executed. What
> is the reason of this behaviour? How does python deal with default
> values (i.e. when are they assigned/created)?
>
> Thanks :)
>
>>>> def a(foo=[]):
> ...  foo.append(1)
> ...  print foo
> ...
>>>> a()
> [1]
>>>> a()
> [1, 1]
>>>> a()
> [1, 1, 1]
>>>> a()
> [1, 1, 1, 1]
>>>> a()
> [1, 1, 1, 1, 1]
>>>> a()
> [1, 1, 1, 1, 1, 1]

Your problem arises because lists are mutable. Because foo (by
default, initially) points to a given list, every time the function is
called, it uses the same list that foo was first pointed to, if the
default argument value is taken.
The way to fix this is to instead do -

def a(foo=None):
    if foo is None:
        foo = []

[toc] | [prev] | [next] | [standalone]


#8480

FromTerry Reedy <tjreedy@udel.edu>
Date2011-06-26 14:46 -0400
Message-ID<mailman.428.1309113996.1164.python-list@python.org>
In reply to#8475
On 6/26/2011 2:28 PM, Marc Aymerich wrote:
> Hi,
> I'm trying to define a function that has an optional parameter which
> should be an empty list whenever it isn't given. However, it takes as
> value the same value as the last time the function was executed. What
> is the reason of this behaviour? How does python deal with default
> values (i.e. when are they assigned/created)?

Our fine Language Reference. Compound Statements chapter, Function 
definitions section, says in bold type: "Default parameter values are 
evaluated when the function definition is executed. ". I presume the 
tutorial says this somewhere too. Read both, along with the first 5 
chanpter of the Library reference.

If you want code executed when you call the function, put it in the body 
that is executed when you call the function

def f(lst = None):
   if lst is None:
     lst = []
     ...

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#8481

FromBenjamin Kaplan <benjamin.kaplan@case.edu>
Date2011-06-26 12:21 -0700
Message-ID<mailman.430.1309116126.1164.python-list@python.org>
In reply to#8475
On Sun, Jun 26, 2011 at 11:28 AM, Marc Aymerich <glicerinu@gmail.com> wrote:
> Hi,
> I'm trying to define a function that has an optional parameter which
> should be an empty list whenever it isn't given. However, it takes as
> value the same value as the last time the function was executed. What
> is the reason of this behaviour? How does python deal with default
> values (i.e. when are they assigned/created)?
>
> Thanks :)
>

So the thing about Python is that you don't actually declare
functions. You create them. def is an executable statement that
creates a function object. Default arguments are part of the function
object, so they get evaluated when the function is created.

>>> foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'foo' is not defined
>>> def foo(a = []) :
...     a.append(1)
...
>>> foo.func_defaults
([],)
>>> foo()
>>> foo.func_defaults
([1],)
>>>

[toc] | [prev] | [next] | [standalone]


#8482

FromCorey Richardson <kb1pkl@aim.com>
Date2011-06-26 15:23 -0400
Message-ID<mailman.431.1309116265.1164.python-list@python.org>
In reply to#8475

[Multipart message — attachments visible in raw view] — view raw

Excerpts from Thomas L. Shinnick's message of Sun Jun 26 14:53:21 -0400 2011:
> See reference manual section 7.6  "Function definitions" under the 
> discussion subtitle "Default parameter values are evaluated when the 
> function definition is executed. "
>          http://docs.python.org/reference/compound_stmts.html#function-definitions
> 
> Yes, this is discussed in many places and many times, but why isn't 
> it in the Python FAQ?  Amazing, yes?
> 

Well, to be fair, I don't think most people actually read the FAQ.
The FAQ does say:

"Default arguments can be used to determine values once, at compile
time instead of at run time. This can only be done for functions or
objects which will not be changed during program execution..."

And he did modify the list during program execution. However this
isn't exactly forthright if you aren't looking for it / know what
you're reading.  I don't think it should be spilled out in detail but
maybe a "there are some tricks involved with mutable default
arguments (for example a list).  Refer to the language reference
(LINK) for more details" would be useful.

But I'm not really certain that would make much of a difference.
I'll Cc this to docs@python.org.
-- 
Corey Richardson
  "Those who deny freedom to others, deserve it not for themselves"
     -- Abraham Lincoln

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web