[Python-Dev] closure semantics
mcherm at mcherm.com
Wed Oct 22 11:11:08 EDT 2003
> But all this is moot unless someone comes up with a way to spell this
> that doesn't require a new keyword or change the meaning of 'global x'
> even if there's an x at an intermediate scope (i.e. you can't change
> 'global x' to mean "search for the next outer scope that defines x").
> And we still have to answer Alex's complaint that newbies misinterpret
> the word 'global'.
I've always thought that "global" statements ought to resemble "import"
statements. Let me explain.
Python doesn't have an "import" statement. It has SEVERAL import
statements. There's "import m", "import m as n", "from m import n",
"from m import n as n2", even the dreaded "import *". However, this
profusion of different statements is NOT usually confusing to people
for three reasons:
(1) All have the same primary keyword "import", suggesting that
they're all related.
(2) All are ultimately concerned with doing the same thing...
ensuring a module is in sys.modules and binding a name in the
current environment so it can be used.
(3) All of these read like english.
Now, it seems to me that "global" is an ideal canidate for similar
treatment. Rather like "import", there is a single thing we want to
control... specifying, when we use the unadorned variable name, which
namespace we wish it to refer to. There are several things we might
want. First, what we already have:
(a) Refers to local namespace. This is the most commonly used
version, and should be (and is!) the default when no "global"
statement is used.
(b) Refers to the module-global namespace. This is the second-most
commonly used scope, and so I'd say it deserves the simplest
form of the "global" statement (rather like "import m" is the
simplest form of "import"). That woud be "global x", and that's
already how Python works.
And a few others we might want:
(c) Refers to nearest enclosing nested-scope namespace in which a
binding of that name already exists.
(d) Refers to the getattr() namespace (normally __dict__) of the
first argument of the function. This is for the "don't like
typing 'self.'" crowd.
(e) Refers to a truly-global (across all modules) namespace
(built-ins I suppose). This is what Alex says newbies guess
that "global" means.
(f) Refers to a specific enclosing nested-scope namespace, in
cases where the nearest nested-scope namespace isn't the one
Personally, I have no use for (d), (e), and (f), and I'd vote c:+1, d:-0
e:-1, f:-1 on including these. But my point is, that a slightly different
form of the "global" statement would satisfy both readability AND
parsability. I'm not feeling particularly creative, so please try to
improve on these phrasings (some aren't parsable... we need forms that
are parsable AND read well):
(c) -- "global x in def"
(d) -- "global x in <self>"
(e) -- "global global x"
(f) -- "x is global in <func>"
Okay... all four of those are lousy. But I still think seeking some
alternate "phrases" or "forms" for the global statement has merit.
-- Michael Chermside
More information about the Python-Dev