What is a function parameter =[] for?

Steven D'Aprano steve at pearwood.info
Sat Nov 21 22:58:14 EST 2015


On Fri, 20 Nov 2015 02:42 am, Ian Kelly wrote:

> On Thu, Nov 19, 2015 at 5:45 AM, Steven D'Aprano <steve at pearwood.info>
> wrote:
>> But if you want the default value to be evaluated exactly once, and once
>> only, there is no real alternative to early binding. You could use a
>> global variable, of course, but that is no solution -- that's a problem
>> waiting to happen.
> 
> It doesn't have to be a global. In a Python with late binding
> defaults, this would work to get early binding:
> 
> def f(x=f.default_x):
>     ...
> 
> f.default_x = something()


Ah, of course it can. Good catch.

As an illustration of how your expectations can colour your thinking, I
actually considered that, but rejected it as a possibility because
f.default_x couldn't be created until the function came into existence, and
the function couldn't come into existence until after f.default_x was
evaluated.

In other words, I was making the complementary error to BartC's: I was still
thinking in terms of early binding, when describing late binding.

In fact, what Python actually does is rather similar, except that instead
of "f.default_x" it uses f.__defaults__[0]. Roughly speaking, the function
declaration

def f(x=something()): ...

using early-binding is somewhat analogous to this using late-binding:

def f(x=f.__defaults__[0]): ...

f.__defaults__ = (something(), )


> Of course, assignment to function attributes is a relatively modern
> thing that is only permitted since Python 2.1, whereas function
> defaults have been around since at least 1.4, so this wouldn't have
> been an option when the semantics were being determined.

I suspect that had Guido decided on late binding as the preferred semantics,
he would have allowed function attributes much earlier.



-- 
Steven




More information about the Python-list mailing list