[Python-3000] Draft PEP for outer scopes
Talin
talin at acm.org
Thu Nov 2 10:42:57 CET 2006
Fredrik Lundh wrote:
> Steven Bethard wrote:
>
>> I don't think that'll really be worth it. I'd be amazed if people
>> didn't expect it to mean "top-level".
>
> as anyone who's spent enough time on c.l.python knows, people expect it
> to mean "application global". it isn't.
>
> alternatively, they expect it to be a scope specifier to be used when
> creating the variable, rather than when referring to it. it isn't.
>
> the exact meaning of "global" is one of the well-known "you only need to
> learn this once" things in Python. a reinterpreted global would fall in
> the same category.
One thing I don't understand in this discussion of re-purposing the
'global' keyword is how you handle the case of an inner function that
*creates* a global.
Right now, you can create a global variable from within a scope, even if
that variable hasn't been declared yet:
def foo():
global x
x = 1
foo()
print x
However, if 'global' is simply a synonym for 'nonlocal', then how does
it know *which* scope to create the variable in?
Let me anticipate one possible answer: "Don't do that". My response
would be: first, being able to do that is occasionally useful, and
second, if we can't do it, then we're back to the notion that global
variables have to be "declared" before they can be used in inner
functions...not exactly within the theme of Python.
However, it just occurred to me that there's another option, one that's
not yet included in Ping's PEP: _Named Lexical Scopes_.
What if 'global' was not a keyword, but rather a name? So when you say
"global x" you really mean that 'x' derives from a lexical scope that
has the name 'global'.
Inner scopes would be named after the function that defines the scope.
So for example:
def foo():
def bar():
foo x # means that 'x' is defined in the 'foo' scope
x = 1
bar()
print x
Admittedly, using a bare non-keyword identifier is probably a bit too
tricky in terms of parsing; Sure, it could be done, but its likely that
it might create some parsing ambiguities that might bite us down the
road. So I'd say go ahead and use a keyword to introduce a reference to
a named scope, for example:
def outer():
def inner1():
def inner2():
scope inner1 x, y = 1, 2
scope outer z = 3
scope global a = "this is a test"
This syntax allows us to refer to any arbitrary outer scope, regardless
of whether a local variable has been defined in that scope or not. Its
also immune to variables changing meaning if the hierarchy of scopes is
rearranged - for example, if we remove 'inner2' from inside 'inner1',
the the references to 'outer' and 'global' still mean exactly the same
thing as they did before.
Also, this scheme does not prevent the compiler from knowing at compile
time exactly what local variables are defined in which scopes.
-- Talin
More information about the Python-3000
mailing list