From: Johan on
Dear all,

Considering this test program:

def tst(a={}):
print 1, a
a['1'] = 1
print 2, a
del a

def tstb(a=[]):
print 1, a
a.append(1)
print 2, a
del a


tst()
tst()

tstb()
tstb()


With output:

tnjx(a)tnjx:~/tst> python tt.py
1 {}
2 {'1': 1}
1 {'1': 1}
2 {'1': 1}
1 []
2 [1]
1 [1]
2 [1, 1]


Would there be a way to ensure that the results does not depend on the
previous call of the function. The desired output is:

1 {}
2 {'1': 1}
1 {}
2 {'1': 1}
1 []
2 [1]
1 []
2 [1]

I know that tst({}) and tstb([]) will work, but is there any way to
still use tst(), tstb()?

Thanks in advance,

Best regards,

Johan

From: Mel on
Johan wrote:

> Dear all,
>
> Considering this test program:
>
> def tst(a={}):
> print 1, a
> a['1'] = 1
> print 2, a
> del a

The idiom to use is

def tst (a=None):
if a is None:
a = {}
# ...

and so on. This means that every call to tst with unspecified a creates its
own empty dict. Ditto for lists.

Mel.


From: Bruno Desthuilliers on
Johan a �crit :
> Dear all,
>
> Considering this test program:
>
> def tst(a={}):

Stop here, we already know what will follow !-)

And yes, it's one of Python's most (in)famous gotchas : default
arguments values are computed only once, at function definition time
(that is, when the def statement is executed).

The correct way to write a function with mutable default arguments is:

def func(arg=None):
if arg is None:
arg = []
# then proceed

HTH
From: MRAB on
Johan wrote:
> Dear all,
>
> Considering this test program:
>
> def tst(a={}):
> print 1, a
> a['1'] = 1
> print 2, a
> del a
>
> def tstb(a=[]):
> print 1, a
> a.append(1)
> print 2, a
> del a
>
[snip]
Do this instead:

def tst(a=None):
if a is None:
a = {}
print 1, a
a['1'] = 1
print 2, a

def tstb(a=None):
if a is None:
a = []
print 1, a
a.append(1)
print 2, a


It's all explained here:

http://effbot.org/zone/default-values.htm