Velocity Reviews > Newbie question - default values of a function

# Newbie question - default values of a function

Bulba!
Guest
Posts: n/a

 12-22-2004

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?

>>> def j(a,i=0):

.... i=i+1
.... return (a, i)
....
>>>
>>> j(2)

(2, 1)
>>> j(3)

(3, 1)
>>> j(5)

(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:

>>> def t(a,i=[0]):

.... 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.

--
It's a man's life in a Python Programming Association.

Dennis Benzinger
Guest
Posts: n/a

 12-22-2004
Bulba! wrote:
> [...]
> But why the following happens?
>
>
>>>>def j(a,i=0):

>
> ... i=i+1
> ... return (a, i)
> ...
>
>>>>j(2)

>
> (2, 1)
>
>>>>j(3)

>
> (3, 1)
>
>>>>j(5)

>
> (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

Fredrik Lundh
Guest
Posts: n/a

 12-22-2004
"Bulba!" wrote:

> Surely the variable i is a mutable object?

nope.

> OK, again:
>
>>>> def t(a,i=[0]):

> ... 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.

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

or the longer version:

http://starship.python.net/crew/mwh/...jectthink.html

</F>

Matt Gerrans
Guest
Posts: n/a

 12-22-2004
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?

Bulba!
Guest
Posts: n/a

 12-22-2004
On Wed, 22 Dec 2004 22:29:44 GMT, "Matt Gerrans" <(E-Mail Removed)>
wrote:

>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.

<snip, thanks>
>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. )

--
It's a man's life in a Python Programming Association.

Bulba!
Guest
Posts: n/a

 12-22-2004

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.

--
It's a man's life in a Python Programming Association.

Dennis Lee Bieber
Guest
Posts: n/a

 12-23-2004
On Wed, 22 Dec 2004 23:37:37 +0100, Bulba! <(E-Mail Removed)> declaimed
the following in comp.lang.python:

> 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. )

--
> ================================================== ============ <
> http://www.velocityreviews.com/forums/(E-Mail Removed) | Wulfraed Dennis Lee Bieber KD6MOG <
> (E-Mail Removed) | Bestiaria Support Staff <
> ================================================== ============ <
> Overflow Page: <http://wlfraed.home.netcom.com/> <

Steve Holden
Guest
Posts: n/a

 12-23-2004
Bulba! wrote:

> 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
--
Steve Holden http://www.holdenweb.com/
Python Web Programming http://pydish.holdenweb.com/
Holden Web LLC +1 703 861 4237 +1 800 494 3119