Newbie question - default values of a function

B

Bulba!

OK. Don't laugh.


There's this example from tutorial, showing how default
value is computed once when defining function and shared
between function calls:

---
def f(a, L=[]):
L.append(a)
return L

print f(1)
print f(2)
print f(3)

This will print

[1]
[1, 2]
[1, 2, 3]
---

(PythonWin 2.3.4 (#53, Oct 18 2004, 20:35:07) [MSC v.1200 32 bit
(Intel)] on win32.)


Tried it, it works as expected.

But why the following happens?
.... i=i+1
.... return (a, i)
.... (5, 1)


From Language Reference:

http://www.python.org/doc/2.3.4/ref/function.html

"Default parameter values are evaluated when the function definition
is executed. This means that the expression is evaluated once, when
the function is defined, and that that same ``pre-computed'' value is
used for each call. This is especially important to understand when a
default parameter is a mutable object, such as a list or a dictionary:
if the function modifies the object (e.g. by appending an item to a
list), the default value is in effect modified. "


Surely the variable i is a mutable object?

OK, again:
.... i[0]=i[0]+1
.... return (a, i)
....
t(1) (1, [1])
t(3) (3, [2])
t(5)
(5, [3])

Yes, it works with the list. But why sharing value between calls
pertains some mutable objects and not the other mutable objects?
I'm stymied.
 
D

Dennis Benzinger

Bulba! said:
[...]
But why the following happens?


... i=i+1
... return (a, i)
...

(2, 1)

(3, 1)

(5, 1)


From Language Reference:

http://www.python.org/doc/2.3.4/ref/function.html

"Default parameter values are evaluated when the function definition
is executed. This means that the expression is evaluated once, when
the function is defined, and that that same ``pre-computed'' value is
used for each call. This is especially important to understand when a
default parameter is a mutable object, such as a list or a dictionary:
if the function modifies the object (e.g. by appending an item to a
list), the default value is in effect modified. "


Surely the variable i is a mutable object?
[...]

No, i is not mutable!
i is a name for a number object which is _not_ mutable
(http://www.python.org/doc/2.4/ref/types.html).

The line i=i+1 creates a new number object with the value 1 and gives it
the name i.


Bye,
Dennis
 
F

Fredrik Lundh

Bulba! said:
Surely the variable i is a mutable object?
nope.

OK, again:
... i[0]=i[0]+1
... return (a, i)
...
t(1) (1, [1])
t(3) (3, [2])
t(5)
(5, [3])

Yes, it works with the list. But why sharing value between calls
pertains some mutable objects and not the other mutable objects?

a variable is not an object.

reset your brain, and read this:

http://www.effbot.org/zone/python-objects.htm

or the longer version:

http://starship.python.net/crew/mwh/hacks/objectthink.html

</F>
 
M

Matt Gerrans

Actually i was not mutable. Try this:

i = 1
id(i)
i += 1
id(i)

Change both of your sample functions to also print the id of the default
variable and that might shed a little more light on the matter.

"i = i + 1" is only changing the local reference called i to refer to an
instance of a different integer object. If you change the original
function to something similar, it will behave similarly:

def f( a, L=[]):
L = L + [a]
return L

Because you are assigning the local reference variable L to a new list,
instead of modifying that original default list that was created.

Is that more clear, or is it now more unclear? ;)
 
B

Bulba!

Actually i was not mutable. Try this:
i = 1
id(i)
i += 1
id(i)

Looks like I will have to read the Language Reference anyway. :-(

Because you are assigning the local reference variable L to a new list,
instead of modifying that original default list that was created.
Is that more clear, or is it now more unclear? ;)

Clear now, but I have to say for someone who's been doing
some C programming in the past it is pretty confusing, because
I'm used to think of any variable as basically a place in memory
with a pointer to it, so anything without #define or const was
considered "mutable" (gawd I still hate pointers).

C-style thinking considered harmful when programming in Python. :eek:)
 
D

Dennis Lee Bieber

Clear now, but I have to say for someone who's been doing
some C programming in the past it is pretty confusing, because
I'm used to think of any variable as basically a place in memory
with a pointer to it, so anything without #define or const was
considered "mutable" (gawd I still hate pointers).
In most languages, variables are "fixed" to "boxes", and
assignment changes the contents of the box.

In Python, variables are "Post-it notes", and assignment moves
the note to whatever box already contains the value.

I = 5
J = I

in C (or other classic language) defines two boxes, and the second
assignment creates a copy of the contents of the first box, storing the
copy in the second box. In Python, there is only one box -- the
immutable "5", and two "notes", the second assignment sticks the "J"
note onto the same box that has the "I" note.

You can't "go into" the box of an immutable -- you can only
attach notes to it, or remove all the notes from it (letting it be
garbage collected). A list or dictionary, however, is mutable. You can
stick notes to the box containing the list (B = aListObject), but you
can also "open" the object in the box, changing what is inside the
object.
C-style thinking considered harmful when programming in Python. :eek:)

--
 
S

Steve Holden

Bulba! said:
Thanks everyone (esp. Fredrik, http://www.effbot.org/zone/index.htm
contains lotsa goodies by him I intend to study), I'm going offline to
reboot my brain. ;-)
Bulba, with reference to your "don't laugh" comment, I'd just like to
say that for a newbie your questions do have a habit of getting to the
nub of what Python's about. I can see you're going to like this language.

regards
Steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top