Something in the function tutorial confused me.

Neil Cerutti horpner at yahoo.com
Mon Aug 6 13:58:16 EDT 2007


On 2007-08-06, Lee Fleming <countblabula at yahoo.com> wrote:
> On Aug 6, 6:25 am, Neil Cerutti <horp... at yahoo.com> wrote:
> Because when the function is called,  the line
>
>
>>     if y is None: y = []
>
>
> is executed, binding a brand new empty list to y. This
> "rebinding" happens every time the function is called, unless
> you provide an argument for y that is not None.
>
> Thanks for the prompt replies. But I am still confused. This is
> what confuses me.... The first time you call the function, say
> with f(23), after the function ends, y no longer equals None.
> Therefore, calling f again, this time like this f(24), should
> make y equal [23,24], because the 'if y == None' test fails, or
> at least I think it fails, because y.append(x) added something
> that was not equal to None during the previous call.
>
> Please help me!

Let's back up a little, and examine a model of the sequence of events.

>>> def f(x, y=None):
...  if y is None:
...    y = []
...  y.append(x)
...  return y
>>> f(2, f(1))
[1, 2]
>>> f(0)
[0]

First, Python reads and executes the function definition. This is
the only time that the default argument expressions of f are
evaluated. None is evaluated, resulting in None, and this is
stored somewhere conveniently inside the function representing f
(see f.func_defaults, for example).

Next, Python evaluates the function call "f(2, f(1))". To do
this, it must first evaluate the function call's arguments. 2
evaluates to 2 (that was easy!).

Next, the expression "f(1)" is evaluated. The name x is bound to
1, and, since y's positional argument was not provided, the name
y is bound to the previously stored default argument.

Now the statements in f are executed. The if statement checks to
see if y is None. It is, so y is rebound to a new empty list
object ("y = []"). Then, the object bound to x (1) is appended to
the list bound to y, and finally that list is returned. It
becomes the second argument of the "outer" call of f.

For this call to f, x is bound to 2, and y is bound to the list
object returned by the previous call to f. Since y is not None
this time, the function simply appends 2 to [1] and returns the
resultant list: [1, 2].

Finally, "f(0)" is evaluated. This calls f, binding x to 0. y is
again bound to the stored default argument, None. As before, this
results in the statement "y = []" binding a new empty list to the
name y. Then 0 is appened to that list, and finally the list is
returned: [0].

-- 
Neil Cerutti
The peace-making meeting scheduled for today has been cancelled due to a
conflict. --Church Bulletin Blooper



More information about the Python-list mailing list