Once-only evaluation of default parameter values function definitions
Shalabh Chaturvedi
shalabh at cafepy.com
Tue Apr 13 09:23:16 EDT 2004
Fred Ma wrote:
> Michael Geary wrote:
>
>
>>> Example#1
>>> ---------
>>> def f(a, L=[]):
>>> L.append(a)
>>> return L
>>>
>>> Example#2
>>> ---------
>>> def f(a, L=None):
>>> if L is None:
>>> L = []
>>> L.append(a)
>>> return L
>>
>>Here's a simpler example:
>>
>>
>>>>>a = []
>>>>>b = a
>>>>>a
>>
>>[]
>>
>>>>>b
>>
>>[]
>>
>>>>>a.append(1)
>>>>>a
>>
>>[1]
>>
>>>>>b
>>
>>[1]
>>
>>See what happened? The statement 'b = a' didn't make a copy of a and
>>store it in b. Instead, it made the name b refer to the same object
>>as a. So, when I said b.append(1), it meant exactly the same thing
>>as if I'd said a.append(1).
>
>
> Thanks, Mike. That's alot clearer. The default value looks like it's
> a persistent object. It is similar to a static local variable in C++.
> In Example#1, that object actually got changed. In contrast, in
> Example#2, the code prevents L from remaining bound to None beyond the
> first line, so the None object never gets changed. In fact, my 2nd
> explanation was close: that there is an unnamed persistent object that
> holds the default value to be bound to L for invocations that don't
> explicity supply an argument for L. The place I went wrong was to say
> that L never gets bound to None again, after it has been bound to a
> caller supplied object on a previous invocation of the function.
>
> Fred
That is correct, L will be bound to None whevever there is no argument
supplied. Also note that the None object is immutable, and cannot be
changed, so this mechanism is safe.
The default value is as 'persistent' as the function itself. Functions
are objects and spring into existance only after Python encounters and
executes the 'def' statement. Python also evaluates the default values
at this point and keeps these objects around, along with the function
definition.
If at a later point you do 'del f', you will delete the function and the
default values (since there is no more use for them, the function cannot
be called). Assuming, of course, that f was the only reference to the
function.
Since the 'name-binding' concept in Python is not exactly the same as
references in C++, I suggest you also read 'How to think like a Pythonista':
http://starship.python.net/crew/mwh/hacks/objectthink.html
for an excellent coverage of one of Python's basic concepts.
--
Shalabh
More information about the Python-list
mailing list