default value in __init__

Aaron "Castironpi" Brady castironpi at gmail.com
Fri Oct 17 13:58:51 EDT 2008


On Oct 17, 6:56 am, Steven D'Aprano <st... at REMOVE-THIS-
cybersource.com.au> wrote:
> On Fri, 17 Oct 2008 23:04:52 +1300, Lawrence D'Oliveiro wrote:
> > In message <Xns9B33BC4CC1480duncanbo... at 127.0.0.1>, Duncan Booth wrote:
>
> >> We already get people asking why code like this doesn't return 3:
>
> >>>>> fns = [ lambda: x for x in range(10) ] fns[3]()
> >> 9
>
> >> ... 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
>
> > The right solution, of course, is
>
> >     fns = [(lambda x : lambda : x)(x) for x in range(10)]
>
> Only if by "right solution" you mean "excessively verbose, confusing, and
> the sort of thing that makes even supporters of lambda cringe".
>
> Yes yes, it's just a factory function written with lambdas. It's still
> ugly and exactly the sort of thing that gives ammunition to lambda-
> haters. Unlike the solution given by Duncan, which is understandable to
> any newbie who has learned about default values and lambda, your solution
> requires an understanding of higher-level functions (functions that
> return functions, for anyone who doesn't recognise the term) that most
> newbies won't have.
>
> And while I don't much care for premature optimization, I will point out
> that creating a factory function just to call it once then throw it away
> is very wasteful, and that waste is demonstrated by the running time
> being more than double that of Duncan's solution:
>
> >>> timeit.Timer('[ lambda y=x: y for x in range(10) ]').repeat()
>
> [7.6332600116729736, 6.9825620651245117, 7.0891578197479248]>>> timeit.Timer('[(lambda x : lambda : x)(x) for x in range(10)]').repeat()
>
> [18.984915971755981, 17.808281898498535, 18.432481050491333]
>
> --
> Steven

No, there's a difference in meaning.  One creates a function that is
called with 0 arguments.  The other creates a function that can be
called with 0 or 1 arguments.  The purpose of a parameter is something
that the caller can supply, but doesn't have to.  It is not for
internal-use-only items.  Nested namespaces and object attributes can
be.



More information about the Python-list mailing list