default value in __init__

Duncan Booth duncan.booth at invalid.invalid
Fri Oct 10 13:30:40 EDT 2008


bearophileHUGS at lycos.com wrote:

>> I don't think simply re-executing the default argument
>> expression on each call works either: that would confuse at least as
>> many people as the current system.
> 
> May I ask you why? I think I don't agree, but I am not sure.
> 
My thought (which may well be wrong) is that people would still expect the 
default argument expression to use the values of variables at the time when 
the function is defined, not the values at the point of calling it.

e.g. in this hypothetical universe:

>>> y = 0
>>> def f(x=y): return x*x

>>> y = 1
>>> f()
1

would certainly be suprising to anyone used to the current behaviour and I 
think would also suprise anyone who hadn't read the manual in sufficient 
details.

We already get people asking why code like this doesn't return 3:

>>> fns = [ lambda: x for x in range(10) ]
>>> fns[3]()
9

i.e. they expect the variable lookup to be done at function definition time 
rather than function call time. This implies to me that some people are 
going to get confused whichever way round these things happen although 
perhaps it is the behaviour of default arguments that makes them expect 
this.

As an aside, making this change to default arguments would mean the 
solution usually proposed to the function scoping question above would no 
longer work:

>>> fns = [ lambda y=x: y for x in range(10) ]
>>> fns[3]()
3

I wonder whether it is the way the default argument expressions are 
embedded inside the function that causes the confusion? If for example 
default arguments were defined like this:

class C:
  @default(d={})
  def __init__(self, i=10, d):
    self.d = d
    self.i = i

would moving the expression before the 'def' make people less inclined to 
be suprised that the object is shared?



More information about the Python-list mailing list