What is a function parameter =[] for?

BartC bc at freeuk.com
Thu Nov 19 16:21:24 EST 2015


On 19/11/2015 19:19, Chris Angelico wrote:
> On Fri, Nov 20, 2015 at 5:19 AM, BartC <bc at freeuk.com> wrote:

> But every choice has consequences. Steven gave you a few examples of
> the consequences of late-binding default arguments. For example, can
> you translate this into (one of) your language(s), and explain the
> semantics of the late binding?
>
> # scope 1: can be a module, an inner function, whatever
> y = 42
> def func(x=y):
>      return x
> def change_y():
>      global y # affect the one in this scope
>      y = 28
>
> # scope 2: another module/function/etc
> from scope1 import func # gain access, however that's done
>
> change_y()
> y = 7
> func()
>
>
> Should this return 7, 28, or 42?

I tried in two languages and both returned 28 the first time. Then I 
realised I'd missed out the y=7 line. Both then printed 7.

It doesn't matter so much if split across modules or not; it depends 
mainly on whether the y in 'y=7' is the same one in 'x=y' and 'y=28' and 
this depends on how it's declared or not and how.

(Both are here if you're interested: http://pastebin.com/0WPrYQw6)

Actually I'm just glad I got one of the results in your list!

(Python returns 42; so that means my languages are more dynamic than 
Python? That's hard to believe!)


  you don't need to look anywhere outside the
> function's own definition to grok its defaults. The default is stable
> (it won't change from one run to another - it'll always be the same
> object). Scope-recognizing late binding would use 28; it re-evaluates
> the expression 'y' in its original scope. This one makes the most
> sense to me, of all late-bind semantics; it also happens to be the
> same semantics as you get if you do the classic "if x is None: x=y"
> late-bind in Python, modulo the effect of the nested scope. But you're
> saying that it "simply substitute[s] the expression", which would mean
> that "func()" is exactly the same as "func(y)". A function default
> argument is therefore able to STEAL STUFF FROM THE CALLER'S SCOPE.
> Sorry for shouting, but if that ain't bizarre, I don't know what is.

Well, it's not quite the same as textual substitution of the default 
value expression, which would use names in the local scope at the call site.

The expression is evaluated using the entities in scope where the 
function is defined, as far as I can determine, although the byte-code 
that evaluates it is at the call site.

This is necessary I think because you want the default value to 
evaluated to the same result independently of the actual call site 
(unless the caller has deliberately manipulated things as in your example).

--



More information about the Python-list mailing list