[Python-Dev] closure semantics

Michael Chermside mcherm at mcherm.com
Wed Oct 22 11:11:08 EDT 2003


Guido writes:
> 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
      you want.

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 mailing list