[Python-ideas] A "local" pseudo-function

MRAB python at mrabarnett.plus.com
Tue May 1 14:00:03 EDT 2018


On 2018-05-01 04:40, Tim Peters wrote:

> [MRAB]
> >> Any binding that's not specified as local is bound in the parent scope:
>
> [Tim]
> > Reverse-engineering the example following, is this a fair way of
> > making that more precise?
> >
> > Given a binding-target name N in scope S, N is bound in scope T, where
> > T is the closest-containing scope (which may be S itself) for which T
> > is either
> >
> > 1. established by a "local:" block that declares name N
> >
> > or
> >
> > 2. not established by a "local: block
>
> Here's an example where I don't know what the consequences of "the
> rules" should be:
>
> def f():
>      a = 10
>      local a:
>          def showa():
>              print("a is", a)
>          showa() # 10
>          a = 20
>          showa() # 20
>          a = 30
>      showa() # 10
The body of "showa" is lexically nested in 'local', so its name "a" is 
the local scope's "a", not the function scope's "a".

Imagine renaming the specified names that are declared 'local' 
throughout the nested portion:

def f():
     a = 10
     local local_a:
         def showa():
             print("a is", local_a)
         showa() # Raises NameError in showa because nothing bound to 
local_a yet.
         local_a = 20
         showa() # 20
         local_a = 30
     showa() # Raises NameError in f because local_a not defined.

> The comments show what the output would be under the "nothing about
> scope rules change" meaning.  They're all obvious (since there is is
> no new scope then - it's all function-local).
>
> But under the other meaning ...?
>
> The twist here is that `def` is an executable statement in Python, and
> is a "binding site" for the name of the function being defined.  So
> despite that `showa` appears to be defined in a new nested lexical
> scope, it's _actually_ bound as a function-local name.  That's bound
> to be surprising to people from other languages:  "I defined it in a
> nested lexical scope, but the name is still visible after that scope
> ends?".
>
> I don't know what the first `showa()` is intended to do.  Presumably
> `a` is unbound at the start of the new nested scope?  So raises
> NameError?  If so, comment that line out so we can make progress ;-)
>
> It seems clear that the second `showa()` will display 20 under any reading.
>
> But the third?  Now we're out of the `local a:` scope, but call a
> function whose textual definition was inside that scope.  What does
> `showa()` do now to find a's value?  f's local `a` had nothing to do
> with the `a` in the nested scope, so presumably it shouldn't display
> 10 now.  What should it do?
> Does the final state of the nested scope's locals need to preserved so
> that showa() can display 30 instead?  Or ...?
>
> Not necessarily complaining  - just fleshing out a bit my earlier
> claim that a world of semantics need to be defined if anything akin to
> a "real scope" is desired.
>



More information about the Python-ideas mailing list