Re: Something in the function tutorial confused me.



On 2007-08-06, Lee Fleming <countblabula@xxxxxxxxx> wrote:
On Aug 6, 6:25 am, Neil Cerutti <horp...@xxxxxxxxx> 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
.



Relevant Pages

  • Re: "also" to balance "else" ?
    ... example more like the following in current Python ... > executes, or if the break is executed, BLOCK3 executes. ... > I think this gives Pythons general flow control some nice symmetrical ...
    (comp.lang.python)
  • Re: conditionally creating functions within a class?
    ... def required_function: ... this (looks like there's not but it may make it into python 3000) ... The problem here is that the "if" statement executes in class scope, ...
    (comp.lang.python)
  • Re: Metaclass with name overloading.
    ... > the class declaration. ... nor does Python need to 'peek' ... Python just executes the class body, ... than shoehorning a declarative language into Python. ...
    (comp.lang.python)
  • Re: Bug in Python class static variable?
    ... When I run "python w.py", ... statement executes: the first 'from a import *' will load and execute ... just imports names defined in the main script *before* a was ... exist until the lines which declare them have been executed. ...
    (comp.lang.python)
  • Re: Bug in Python class static variable?
    ... When I run "python w.py", ... statement executes: the first 'from a import *' will load and execute ... just imports names defined in the main script *before* a was ... exist until the lines which declare them have been executed. ...
    (comp.lang.python)