On 2007-08-06, Lee Fleming <[EMAIL PROTECTED]> wrote: > On Aug 6, 6:25 am, Neil Cerutti <[EMAIL PROTECTED]> 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 -- http://mail.python.org/mailman/listinfo/python-list